/* FUSE: Filesystem in Userspace Copyright (C) 2005 Csaba Henk This program can be distributed under the terms of the GNU LGPL. See the file COPYING.LIB. */ #include "fuse.h" #include #include #include #include #include #include #define FUSERMOUNT_PROG "mount_fusefs" void fuse_unmount(const char *mountpoint) { char dev[128]; char *ssc, *umount_cmd; FILE *sf; int rv; char *seekscript = "/usr/bin/fstat /dev/fuse* | " "/usr/bin/awk 'BEGIN{ getline; if (! ($3 == \"PID\" && $10 == \"NAME\")) exit 1; }; " " { if ($3 == %d) print $10; }' | " "/usr/bin/sort | " "/usr/bin/uniq | " "/usr/bin/awk '{ i += 1; if (i > 1){ exit 1; }; printf; }; END{ if (i == 0) exit 1; }'"; asprintf(&ssc, seekscript, getpid()); errno = 0; sf = popen(ssc, "r"); if (! sf) return; fgets(dev, sizeof(dev), sf); rv = pclose(sf); if (rv) return; asprintf(&umount_cmd, "/sbin/umount %s", dev); system(umount_cmd); } int fuse_mount(const char *mountpoint, const char *opts) { const char *mountprog = FUSERMOUNT_PROG; int fd; char *fdnam, *dev; int pid; fdnam = getenv("FUSE_DEV_FD"); if (fdnam) { char *ep; fd = strtol(fdnam, &ep, 10); if (*ep != '\0') { fprintf(stderr, "invalid value given in FUSE_DEV_FD\n"); return -1; } if (fd < 0) return -1; goto mount; } dev = getenv("FUSE_DEV_NAME"); if (! dev) dev = "/dev/fuse"; if ((fd = open(dev, O_RDWR)) < 0) { perror("fuse: failed to open fuse device"); return -1; } mount: if (getenv("FUSE_NO_MOUNT") || ! mountpoint) goto out; pid = fork(); if (pid == -1) { perror("fuse: fork() failed"); close(fd); return -1; } if (pid == 0) { pid = fork(); if (pid == -1) { perror("fuse: fork() failed"); close(fd); exit(1); } if (pid == 0) { const char *argv[32]; int a = 0; if (! fdnam) asprintf(&fdnam, "%d", fd); argv[a++] = mountprog; if (opts) { argv[a++] = "-o"; argv[a++] = opts; } argv[a++] = fdnam; argv[a++] = mountpoint; argv[a++] = NULL; setenv("MOUNT_FUSEFS_SAFE", "1", 1); setenv("MOUNT_FUSEFS_NOINTERACTIVE", "1", 1); execvp(mountprog, (char **) argv); perror("fuse: failed to exec mount program"); exit(1); } exit(0); } waitpid(pid, NULL, 0); out: return fd; }