aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2005-11-29 23:47:10 +0000
committerRob Landley <rob@landley.net>2005-11-29 23:47:10 +0000
commit1d589b2e2d6e9e0af719b481c7ef333bc73e2a7a (patch)
tree4a6c23fb08ab9c8fa2e3ad68c9425f65a3fe6a21 /libbb
parent70678bc5b65a62176a6b41b4481e7f4f274a9c93 (diff)
downloadbusybox-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.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 }