losetup: implement -r option. Closes 4033.
No binary (build failed)
—
(log yok)
| @@ -1164,7 +1164,7 @@ extern int del_loop(const char *device) FAST_FUNC; | |
| /* If *devname is not NULL, use that name, otherwise try to find free one, | |
| * malloc and return it in *devname. | |
| * return value: 1: read-only loopdev was setup, 0: rw, < 0: error */ | |
| - | extern int set_loop(char **devname, const char *file, unsigned long long offset) FAST_FUNC; |
| + | extern int set_loop(char **devname, const char *file, unsigned long long offset, int ro) FAST_FUNC; |
| /* Like bb_ask below, but asks on stdin with no timeout. */ | |
| char *bb_ask_stdin(const char * prompt) FAST_FUNC; | |
| @@ -84,7 +84,7 @@ int FAST_FUNC del_loop(const char *device) | |
| search will re-use an existing loop device already bound to that | |
| file/offset if it finds one. | |
| */ | |
| - | int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset) |
| + | int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset, int ro) |
| { | |
| char dev[LOOP_NAMESIZE]; | |
| char *try; | |
| @@ -93,11 +93,13 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse | |
| int i, dfd, ffd, mode, rc = -1; | |
| /* Open the file. Barf if this doesn't work. */ | |
| - | mode = O_RDWR; |
| + | mode = ro ? O_RDONLY : O_RDWR; |
| ffd = open(file, mode); | |
| if (ffd < 0) { | |
| - | mode = O_RDONLY; |
| - | ffd = open(file, mode); |
| + | if (mode != O_RDONLY) { |
| + | mode = O_RDONLY; |
| + | ffd = open(file, mode); |
| + | } |
| if (ffd < 0) | |
| return -errno; | |
| } | |
| @@ -8,11 +8,12 @@ | |
| */ | |
| //usage:#define losetup_trivial_usage | |
| - | //usage: "[-o OFS] LOOPDEV FILE - associate loop devices\n" |
| + | //usage: "[-r] [-o OFS] LOOPDEV FILE - associate loop devices\n" |
| //usage: " losetup -d LOOPDEV - disassociate\n" | |
| //usage: " losetup [-f] - show" | |
| //usage:#define losetup_full_usage "\n\n" | |
| //usage: " -o OFS Start OFS bytes into FILE" | |
| + | //usage: "\n -r Read-only" |
| //usage: "\n -f Show first free loop device" | |
| //usage: | |
| //usage:#define losetup_notes_usage | |
| @@ -37,11 +38,12 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) | |
| OPT_d = (1 << 0), | |
| OPT_o = (1 << 1), | |
| OPT_f = (1 << 2), | |
| + | OPT_r = (1 << 3), /* must be last */ |
| }; | |
| - | /* max 2 args, all opts are mutually exclusive */ |
| + | /* max 2 args, -d,-o,-f opts are mutually exclusive */ |
| opt_complementary = "?2:d--of:o--df:f--do"; | |
| - | opt = getopt32(argv, "do:f", &opt_o); |
| + | opt = getopt32(argv, "do:fr", &opt_o); |
| argv += optind; | |
| if (opt == OPT_o) | |
| @@ -63,12 +65,12 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) | |
| bb_show_usage(); | |
| if (argv[1]) { | |
| - | /* [-o OFS] BLOCKDEV FILE */ |
| - | if (set_loop(&argv[0], argv[1], offset) < 0) |
| + | /* [-r] [-o OFS] BLOCKDEV FILE */ |
| + | if (set_loop(&argv[0], argv[1], offset, (opt / OPT_r)) < 0) |
| bb_simple_perror_msg_and_die(argv[0]); | |
| return EXIT_SUCCESS; | |
| } | |
| - | /* [-o OFS] BLOCKDEV */ |
| + | /* [-r] [-o OFS] BLOCKDEV */ |
| s = query_loop(argv[0]); | |
| if (!s) | |
| bb_simple_perror_msg_and_die(argv[0]); | |
| @@ -78,7 +80,7 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) | |
| return EXIT_SUCCESS; | |
| } | |
| - | /* [-o OFS|-f] with no params */ |
| + | /* [-r] [-o OFS|-f] with no params */ |
| n = 0; | |
| while (1) { | |
| char *s; | |
| @@ -1809,7 +1809,7 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |
| if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) { | |
| loopFile = bb_simplify_path(mp->mnt_fsname); | |
| mp->mnt_fsname = NULL; // will receive malloced loop dev name | |
| - | if (set_loop(&mp->mnt_fsname, loopFile, 0) < 0) { |
| + | if (set_loop(&mp->mnt_fsname, loopFile, 0, /*ro:*/ 0) < 0) { |
| if (errno == EPERM || errno == EACCES) | |
| bb_error_msg(bb_msg_perm_denied_are_you_root); | |
| else | |