the beginnings of a proper man page for busybox.
[oweals/busybox.git] / umount.c
index 522498be72323e77c63c28d53c2283e6dc87eb12..af1b3a43e2a95c3b39f1b86f67deafabc1e0037c 100644 (file)
--- a/umount.c
+++ b/umount.c
 #include <fstab.h>
 #include <errno.h>
 
+#if defined BB_FEATURE_MOUNT_LOOP
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/loop.h>
+
+static int del_loop(const char *device);
+#endif
+
 static const char umount_usage[] = 
 "Usage: umount [flags] filesystem|directory\n\n"
 "Flags:\n"
@@ -44,23 +52,54 @@ static int useMtab = TRUE;
 static int umountAll = FALSE;
 extern const char mtab_file[]; /* Defined in utility.c */
 
-#if ! defined BB_MTAB
-#define do_umount( blockDevice, useMtab) umount( blockDevice)
-#else
 static int 
 do_umount(const char* name, int useMtab)
 {
-    int status = umount(name);
+    int status;
+
+#if defined BB_FEATURE_MOUNT_LOOP
+    /* check to see if this is a loop device */
+    struct stat fst;
+    char dev[20];
+    const char *oldname = NULL;
+    int i;
+    
+    if (stat(name, &fst)) {
+       fprintf(stderr, "umount: %s: %s\n", name, strerror(errno));
+       exit(1);
+    }
+    for (i = 0 ; i <= 7 ; i++) {
+       struct stat lst;
+       sprintf(dev, "/dev/loop%d", i);
+       if (stat(dev, &lst))
+           continue;
+       if (lst.st_dev == fst.st_dev) {
+           oldname = name;
+           name = dev;
+           break;
+       }
+    }
+#endif
+
+    status = umount(name);
 
+#if defined BB_FEATURE_MOUNT_LOOP
+    if (!strncmp("/dev/loop", name, 9)) { /* this was a loop device, delete it */
+       del_loop(name);
+       if (oldname != NULL)
+           name = oldname;
+    }
+#endif
+#if defined BB_MTAB
     if ( status == 0 ) {
        if ( useMtab==TRUE )
            erase_mtab(name);
        return 0;
     }
-    else 
-       return( status);
-}
+    else
 #endif
+       return(status);
+}
 
 static int
 umount_all(int useMtab)
@@ -107,13 +146,6 @@ umount_all(int useMtab)
 extern int
 umount_main(int argc, char** argv)
 {
-    int i=0;
-    char **foo=argv;
-    while(*foo) {
-       fprintf(stderr, "argv[%d]='%s'\n", i++, *foo);
-       foo++;
-    }
-
     if (argc < 2) {
        usage( umount_usage); 
     }
@@ -142,7 +174,24 @@ umount_main(int argc, char** argv)
        exit (TRUE);
     else {
        perror("umount");
-       exit( FALSE);
+       exit(FALSE);
     }
 }
 
+#if defined BB_FEATURE_MOUNT_LOOP
+static int del_loop(const char *device)
+{
+       int fd;
+
+       if ((fd = open(device, O_RDONLY)) < 0) {
+               perror(device);
+               exit(1);
+       }
+       if (ioctl(fd, LOOP_CLR_FD, 0) < 0) {
+               perror("ioctl: LOOP_CLR_FD");
+               exit(1);
+       }
+       close(fd);
+       return(0);
+}
+#endif