On 6 May 2008 at 14:19, Walter Roberson wrote:
> ... and yes, people *do* make mistakes. For example, in the recent
> sys_MOUNT thread you were keen on, the answer you cited as "accurate"
> was *not* accurate.
There was indeed an inaccuracy in my answer, and it would have been a
courtesy to the OP and others reading this discussion if you'd pointed
it out instead of getting on your high-horse.
Specifically, I said:
> If you really want to work programatically, you can open one of the
> loop devices, perform an ioctl on it (request LOOP_SET_FD with extra
> argument "/home/sam/myfile.img"), then use mount(2).
This is wrong: the extra argument should be a file descriptor, not a
path name.
Here's a knock-up example of mounting a file programatically with a loop
device (of course it needs to be run with sufficient privileges to set up
the loop device and mount it).
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <linux/loop.h>
#define FILE_TO_MOUNT "/tmp/foo.iso"
#define MOUNT_PATH "/mnt"
int main(int argc, char **argv)
{
char dev[]="/dev/loop0";
int i, fd, fd2;
struct stat statbuf;
struct loop_info loopinfo;
/* find a free loop device */
for(i=0; i<8; i++) {
dev[9]='0'+i;
if( stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode) )
if((fd = open (dev, O_RDONLY)) >= 0) {
if(ioctl(fd, LOOP_GET_STATUS, &loopinfo) && (errno == ENXIO))
break; /* got one! */
close(fd);
}
fd=-1;
}
if(fd==-1) {
fprintf(stderr, "%s: couldn't find free loop device\n", *argv);
return 1;
}
/* set up the loop device */
if((fd2=open(FILE_TO_MOUNT, O_RDONLY)) < 0) {
fprintf(stderr, "%s: failed to open " FILE_TO_MOUNT "\n", *argv);
return 2;
}
if(ioctl(fd, LOOP_SET_FD, (void *) fd2)) {
fprintf(stderr, "%s: ioctl failed on %s\n", *argv, dev);
return 3;
}
/* do the mount */
if(mount(dev, MOUNT_PATH, "iso9660", MS_RDONLY, NULL)) {
fprintf(stderr, "%s: failed to mount %s on " MOUNT_PATH "\n", *argv,
dev);
if (ioctl (fd, LOOP_CLR_FD, 0))
fprintf(stderr, "%s: failed to clear %s\n", *argv, dev);
return 4;
}
/* pause */
printf("Mounted " FILE_TO_MOUNT " at " MOUNT_PATH " using %s\n"
"Press enter to umount...\n", dev);
getchar();
/* do the umount */
if(umount(MOUNT_PATH)) {
fprintf(stderr, "%s: failed to umount %s on " MOUNT_PATH "\n", *argv,
dev);
if (ioctl (fd, LOOP_CLR_FD, 0))
fprintf(stderr, "%s: failed to clear %s\n", *argv, dev);
return 5;
}
/* clean up */
close(fd2);
if (ioctl (fd, LOOP_CLR_FD, 0)) {
fprintf(stderr, "%s: failed to clear %s\n", *argv, dev);
return 6;
}
close(fd);
fprintf(stderr, "Umounted %s and cleared %s\n", MOUNT_PATH, dev);
return 0;
}


|