diff options
author | Rob Landley <rob@landley.net> | 2005-11-29 23:47:10 +0000 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2005-11-29 23:47:10 +0000 |
commit | 1d589b2e2d6e9e0af719b481c7ef333bc73e2a7a (patch) | |
tree | 4a6c23fb08ab9c8fa2e3ad68c9425f65a3fe6a21 /libbb | |
parent | 70678bc5b65a62176a6b41b4481e7f4f274a9c93 (diff) | |
download | busybox-w32-1d589b2e2d6e9e0af719b481c7ef333bc73e2a7a.tar.gz busybox-w32-1d589b2e2d6e9e0af719b481c7ef333bc73e2a7a.tar.bz2 busybox-w32-1d589b2e2d6e9e0af719b481c7ef333bc73e2a7a.zip |
Fix losetup so that it A) actually works again, B) has much better error
messages, C) can show the current association (if any) when called
with only one argument. Update the documentation a lot too.
Remind me to add a test suite for this thing. I think I've figured out
how to handle root-only testsuites...
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/loop.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/libbb/loop.c b/libbb/loop.c index 10217931b..00e3d6236 100644 --- a/libbb/loop.c +++ b/libbb/loop.c | |||
@@ -51,15 +51,30 @@ typedef struct { | |||
51 | } bb_loop_info; | 51 | } bb_loop_info; |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | extern int del_loop(const char *device) | 54 | char *query_loop(const char *device) |
55 | { | 55 | { |
56 | int fd,rc=0; | 56 | int fd; |
57 | bb_loop_info loopinfo; | ||
58 | char *dev=0; | ||
59 | |||
60 | if ((fd = open(device, O_RDONLY)) < 0) return 0; | ||
61 | if (!ioctl(fd, BB_LOOP_GET_STATUS, &loopinfo)) | ||
62 | dev=bb_xasprintf("%ld %s", (long) loopinfo.lo_offset, | ||
63 | loopinfo.lo_file_name); | ||
64 | close(fd); | ||
57 | 65 | ||
58 | if ((fd = open(device, O_RDONLY)) < 0) rc=1; | 66 | return dev; |
59 | else { | 67 | } |
60 | if (ioctl(fd, LOOP_CLR_FD, 0) < 0) rc=1; | 68 | |
61 | close(fd); | 69 | |
62 | } | 70 | int del_loop(const char *device) |
71 | { | ||
72 | int fd, rc; | ||
73 | |||
74 | if ((fd = open(device, O_RDONLY)) < 0) return 1; | ||
75 | rc=ioctl(fd, LOOP_CLR_FD, 0); | ||
76 | close(fd); | ||
77 | |||
63 | return rc; | 78 | return rc; |
64 | } | 79 | } |
65 | 80 | ||
@@ -69,9 +84,9 @@ extern int del_loop(const char *device) | |||
69 | search will re-use an existing loop device already bound to that | 84 | search will re-use an existing loop device already bound to that |
70 | file/offset if it finds one. | 85 | file/offset if it finds one. |
71 | */ | 86 | */ |
72 | extern int set_loop(char **device, const char *file, int offset) | 87 | int set_loop(char **device, const char *file, int offset) |
73 | { | 88 | { |
74 | char dev[20]; | 89 | char dev[20], *try; |
75 | bb_loop_info loopinfo; | 90 | bb_loop_info loopinfo; |
76 | struct stat statbuf; | 91 | struct stat statbuf; |
77 | int i, dfd, ffd, mode, rc=1; | 92 | int i, dfd, ffd, mode, rc=1; |
@@ -81,20 +96,21 @@ extern int set_loop(char **device, const char *file, int offset) | |||
81 | return errno; | 96 | return errno; |
82 | 97 | ||
83 | /* Find a loop device. */ | 98 | /* Find a loop device. */ |
99 | try=*device ? : dev; | ||
84 | for(i=0;rc;i++) { | 100 | for(i=0;rc;i++) { |
85 | sprintf(dev, LOOP_FORMAT, i++); | 101 | sprintf(dev, LOOP_FORMAT, i++); |
86 | /* Ran out of block devices, return failure. */ | 102 | /* Ran out of block devices, return failure. */ |
87 | if(stat(*device ? *device : dev, &statbuf) || | 103 | if(stat(try, &statbuf) || !S_ISBLK(statbuf.st_mode)) { |
88 | !S_ISBLK(statbuf.st_mode)) { | ||
89 | rc=ENOENT; | 104 | rc=ENOENT; |
90 | break; | 105 | break; |
91 | } | 106 | } |
92 | /* Open the sucker and check its loopiness. */ | 107 | /* Open the sucker and check its loopiness. */ |
93 | if((dfd=open(dev, mode))<0 && errno==EROFS) | 108 | if((dfd=open(try, mode))<0 && errno==EROFS) |
94 | dfd=open(dev,mode=O_RDONLY); | 109 | dfd=open(try,mode=O_RDONLY); |
95 | if(dfd<0) continue; | 110 | if(dfd<0) continue; |
96 | 111 | ||
97 | rc=ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo); | 112 | rc=ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo); |
113 | |||
98 | /* If device free, claim it. */ | 114 | /* If device free, claim it. */ |
99 | if(rc && errno==ENXIO) { | 115 | if(rc && errno==ENXIO) { |
100 | memset(&loopinfo, 0, sizeof(loopinfo)); | 116 | memset(&loopinfo, 0, sizeof(loopinfo)); |
@@ -110,7 +126,7 @@ extern int set_loop(char **device, const char *file, int offset) | |||
110 | without using losetup manually is problematic.) | 126 | without using losetup manually is problematic.) |
111 | */ | 127 | */ |
112 | } else if(strcmp(file,loopinfo.lo_file_name) | 128 | } else if(strcmp(file,loopinfo.lo_file_name) |
113 | || offset!=loopinfo.lo_offset) rc=1; | 129 | || offset!=loopinfo.lo_offset) rc=-1; |
114 | close(dfd); | 130 | close(dfd); |
115 | if(*device) break; | 131 | if(*device) break; |
116 | } | 132 | } |