aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
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 }