|  | 
 | #include <sys/mount.h> | 
 | #include <sys/stat.h> | 
 | #include <fcntl.h> | 
 | #include <stdio.h> | 
 | #include <string.h> | 
 | #include <unistd.h> | 
 | #include <linux/loop.h> | 
 | #include <errno.h> | 
 |  | 
 | #define LOOPDEV_MAXLEN 64 | 
 | #define LOOP_MAJOR 7 | 
 |  | 
 | static int is_loop(char *dev) | 
 | { | 
 |     struct stat st; | 
 |     int ret = 0; | 
 |  | 
 |     if (stat(dev, &st) == 0) { | 
 |         if (S_ISBLK(st.st_mode) && (major(st.st_rdev) == LOOP_MAJOR)) { | 
 |             ret = 1; | 
 |         } | 
 |     } | 
 |  | 
 |     return ret; | 
 | } | 
 |  | 
 | static int is_loop_mount(const char* path, char *loopdev) | 
 | { | 
 |     FILE* f; | 
 |     int count; | 
 |     char device[256]; | 
 |     char mount_path[256]; | 
 |     char rest[256]; | 
 |     int result = 0; | 
 |      | 
 |     f = fopen("/proc/mounts", "r"); | 
 |     if (!f) { | 
 |         fprintf(stdout, "could not open /proc/mounts: %s\n", strerror(errno)); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     do { | 
 |         count = fscanf(f, "%255s %255s %255s\n", device, mount_path, rest); | 
 |         if (count == 3) { | 
 |             if (is_loop(device) && strcmp(path, mount_path) == 0) { | 
 |                 strlcpy(loopdev, device, LOOPDEV_MAXLEN); | 
 |                 result = 1; | 
 |                 break; | 
 |             } | 
 |         } | 
 |     } while (count == 3); | 
 |  | 
 |     fclose(f); | 
 |     return result; | 
 | } | 
 |  | 
 | int umount_main(int argc, char *argv[]) | 
 | { | 
 |     int loop, loop_fd; | 
 |     char loopdev[LOOPDEV_MAXLEN]; | 
 |  | 
 |     if(argc != 2) { | 
 |         fprintf(stderr,"umount <path>\n"); | 
 |         return 1; | 
 |     } | 
 |  | 
 |     loop = is_loop_mount(argv[1], loopdev); | 
 |     if (umount(argv[1])) { | 
 |         fprintf(stderr, "failed: %s\n", strerror(errno)); | 
 |         return 1; | 
 |     } | 
 |  | 
 |     if (loop) { | 
 |         // free the loop device | 
 |         loop_fd = open(loopdev, O_RDONLY); | 
 |         if (loop_fd < 0) { | 
 |             fprintf(stderr, "open loop device failed: %s\n", strerror(errno)); | 
 |             return 1; | 
 |         } | 
 |         if (ioctl(loop_fd, LOOP_CLR_FD, 0) < 0) { | 
 |             fprintf(stderr, "ioctl LOOP_CLR_FD failed: %s\n", strerror(errno)); | 
 |             return 1; | 
 |         } | 
 |  | 
 |         close(loop_fd); | 
 |     } | 
 |  | 
 |     return 0; | 
 | } |