mirror of
https://github.com/libfuse/libfuse.git
synced 2024-11-24 04:34:13 +08:00
136 lines
2.8 KiB
C
136 lines
2.8 KiB
C
/*
|
|
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* | "
|
|
"/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;
|
|
}
|