diff options
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 | } |