Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 92 lines (76 sloc) 1.975 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91

#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;
    int path_length = strlen(path);
    
    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;
}
Something went wrong with that request. Please try again.