aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorlandley <landley@69ca8d6d-28ef-0310-b511-8ec308f3f277>2005-11-29 23:47:10 +0000
committerlandley <landley@69ca8d6d-28ef-0310-b511-8ec308f3f277>2005-11-29 23:47:10 +0000
commitaf977c6e219aa2e3f45e3f6e73c9cedcf7bcc350 (patch)
tree4a6c23fb08ab9c8fa2e3ad68c9425f65a3fe6a21 /libbb
parent929e65144578d72d3e5f72a1c0bc20edb42f1c3a (diff)
downloadbusybox-w32-af977c6e219aa2e3f45e3f6e73c9cedcf7bcc350.tar.gz
busybox-w32-af977c6e219aa2e3f45e3f6e73c9cedcf7bcc350.tar.bz2
busybox-w32-af977c6e219aa2e3f45e3f6e73c9cedcf7bcc350.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... git-svn-id: svn://busybox.net/trunk/busybox@12582 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'libbb')
-rw-r--r--libbb/loop.c44
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
54extern int del_loop(const char *device) 54char *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 } 70int 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 */
72extern int set_loop(char **device, const char *file, int offset) 87int 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 }