diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2005-11-16 13:00:24 +0000 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2005-11-16 13:00:24 +0000 |
commit | b3f9972a859e95cf836c0044c82fcf312afc566e (patch) | |
tree | 8eaad737402f56ae53f6ed57e2b0878830e652eb /lib/mount_bsd.c | |
parent | 666aea72dfafcf8e93d9c781d1d8d3e644bd6949 (diff) |
merge FreeBSD stuff
Diffstat (limited to 'lib/mount_bsd.c')
-rw-r--r-- | lib/mount_bsd.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c new file mode 100644 index 0000000..0111b14 --- /dev/null +++ b/lib/mount_bsd.c @@ -0,0 +1,133 @@ +/* + FUSE: Filesystem in Userspace + Copyright (C) 2005 Csaba Henk <csaba.henk@creo.hu> + + This program can be distributed under the terms of the GNU LGPL. + See the file COPYING.LIB. +*/ + +#include "fuse.h" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/wait.h> + +#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* |\n" + "/usr/bin/awk '{if ($3 == %d) print $10}' |\n" + "/usr/bin/sort |\n" + "/usr/bin/uniq |\n" + "/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"); + 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); + execvp(mountprog, (char **) argv); + perror("fuse: failed to exec mount program"); + exit(1); + } + + exit(0); + } + + waitpid(pid, NULL, 0); + +out: + return fd; +} |