aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <miklos@szeredi.hu>2002-10-25 11:40:14 +0000
committerGravatar Miklos Szeredi <miklos@szeredi.hu>2002-10-25 11:40:14 +0000
commitd6e9f88da7cea46cf63d30911b9297ccf1befd5c (patch)
treec7ebc671683f4c75fd09c040fca3b3b0f23ec0b8
parent5e5d61fea489aff7b2f70840060ad19c9e6c2bbe (diff)
use fuse_mount in fuse_main
-rw-r--r--ChangeLog5
-rw-r--r--include/fuse.h5
-rw-r--r--lib/helper.c152
-rwxr-xr-xmakeconf.sh6
-rw-r--r--util/Makefile.am3
-rw-r--r--util/fuse_ioslave.c61
-rw-r--r--util/fusermount.c52
7 files changed, 148 insertions, 136 deletions
diff --git a/ChangeLog b/ChangeLog
index 8c01735..e9a14af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2002-10-25 Miklos Szeredi <mszeredi@inf.bme.hu>
+
+ * Use Mark Glines' fd passing method for default operation instead
+ of old reexec
+
2002-10-22 Miklos Szeredi <mszeredi@inf.bme.hu>
* fix "Stale NFS file handle" bug caused by changes in 2.4.19
diff --git a/include/fuse.h b/include/fuse.h
index 78cd877..6a3ed3a 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -116,10 +116,11 @@ extern "C" {
* fuse_new()
*
* @param mountpoint the mount point path
- * @param mount arguments (passed to the fusermount program)
+ * @param args array of arguments to be passed to fusermount (NULL
+ * terminated). Can be NULL if no arguments are needed.
* @return the control file descriptor on success, -1 on failure
*/
-int fuse_mount(const char *mountpoint, const char *mount_args);
+int fuse_mount(const char *mountpoint, const char *args[]);
/**
* Create a new FUSE filesystem.
diff --git a/lib/helper.c b/lib/helper.c
index f523f99..559e992 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -20,8 +20,11 @@
#include <fcntl.h>
#include <sys/wait.h>
-#define FUSE_MOUNTED_ENV "_FUSE_MOUNTED"
-#define FUSE_UMOUNT_CMD_ENV "_FUSE_UNMOUNT_CMD"
+#define FUSE_MOUNTED_ENV "_FUSE_MOUNTED"
+#define FUSE_UMOUNT_CMD_ENV "_FUSE_UNMOUNT_CMD"
+#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
+
+#define FUSERMOUNT_PROG "fusermount"
static void usage(char *progname)
{
@@ -35,51 +38,22 @@ static void usage(char *progname)
exit(1);
}
-static void fuse_unmount()
-{
- close(0);
- system(getenv(FUSE_UMOUNT_CMD_ENV));
-}
+static char umount_cmd[1024];
+static int fuse_fd;
-static int fuse_mount_obsolete(int *argcp, char **argv)
+static void fuse_unmount()
{
- char *isreexec = getenv(FUSE_MOUNTED_ENV);
-
- if(isreexec == NULL) {
- int i;
- int argc = *argcp;
- char *mountprog = "fusermount";
- char **newargv = (char **) malloc((1 + argc + 1) * sizeof(char *));
-
- if(argc < 2 || argv[1][0] == '-')
- usage(argv[0]);
-
- /* oldargs: "PROG MOUNTPOINT ARGS..."
- newargs: "fusermount MOUNTPOINT PROG ARGS..." */
-
- newargv[0] = mountprog;
- newargv[1] = argv[1];
- newargv[2] = argv[0];
- for(i = 2; i < argc; i++)
- newargv[i+1] = argv[i];
- newargv[i+1] = NULL;
-
- execvp(mountprog, newargv);
- fprintf(stderr, "fuse: failed to exec %s: %s\n", mountprog,
- strerror(errno));
- return -1;
- }
- unsetenv(FUSE_MOUNTED_ENV);
-
- /* The actual file descriptor is stdin */
- return 0;
+ close(fuse_fd);
+ if(umount_cmd[0] != '\0')
+ system(umount_cmd);
}
/* return value:
* >= 0 => fd
* -1 => error
*/
-int receive_fd(int fd) {
+static int receive_fd(int fd)
+{
struct msghdr msg;
struct iovec iov;
char buf[1];
@@ -120,46 +94,63 @@ int receive_fd(int fd) {
return *(int*)CMSG_DATA(cmsg);
}
-int fuse_mount(const char *mountpoint, const char *mount_args)
+int fuse_mount(const char *mountpoint, const char *args[])
{
+ const char *mountprog = FUSERMOUNT_PROG;
int fds[2], pid;
- int rv, fd;
- char env[10];
+ int res;
+ int rv;
+
+ snprintf(umount_cmd, sizeof(umount_cmd) - 1, "%s -u %s", mountprog,
+ mountpoint);
- /* FIXME: parse mount_args (or just pass it to fusermount ???) */
- mount_args = mount_args;
-
- /* make sure the socket fds are greater than 0 */
- fd = open("/dev/null",O_RDONLY);
- rv = socketpair(PF_UNIX,SOCK_STREAM,0,fds);
- close(fd);
- if(rv) {
- fprintf(stderr,"fuse: failed to socketpair()\n");
- close(fd);
+ res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds);
+ if(res == -1) {
+ perror("fuse: socketpair() failed");
return -1;
}
+
pid = fork();
- if(pid < 0) {
- fprintf(stderr,"fuse: failed to fork()\n");
+ if(pid == -1) {
+ perror("fuse: fork() failed");
close(fds[0]);
close(fds[1]);
return -1;
}
+
if(pid == 0) {
+ char env[10];
+ char **newargv;
+ int numargs = 0;
+ int actr;
+ int i;
+
+ if(args != NULL)
+ while(args[numargs] != NULL)
+ numargs ++;
+
+ newargv = (char **) malloc((1 + numargs + 2) * sizeof(char *));
+ actr = 0;
+ newargv[actr++] = strdup(mountprog);
+ for(i = 0; i < numargs; i++)
+ newargv[actr++] = strdup(args[i]);
+ newargv[actr++] = strdup(mountpoint);
+ newargv[actr++] = NULL;
+
close(fds[1]);
- fcntl(fds[0],F_SETFD,0);
- snprintf(env,sizeof(env),"%i",fds[0]);
- setenv("_FUSE_IOSLAVE_FD",env,1);
- execlp("fusermount","fusermount",mountpoint,"fuse_ioslave",NULL);
- fprintf(stderr,"fuse: failed to exec fusermount\n");
+ fcntl(fds[0], F_SETFD, 0);
+ snprintf(env, sizeof(env), "%i", fds[0]);
+ setenv(FUSE_COMMFD_ENV, env, 1);
+ execvp(mountprog, newargv);
+ perror("fuse: failed to exec fusermount");
exit(1);
}
- fd = fds[1];
close(fds[0]);
- rv = receive_fd(fd);
- close(fd);
- waitpid(pid,NULL,0); /* bury zombie */
+ rv = receive_fd(fds[1]);
+ close(fds[1]);
+ waitpid(pid, NULL, 0); /* bury zombie */
+
return rv;
}
@@ -194,20 +185,41 @@ static void set_signal_handlers()
void fuse_main(int argc, char *argv[], const struct fuse_operations *op)
{
- int fd;
- int argctr;
+ int argctr = 1;
int flags;
int multithreaded;
struct fuse *fuse;
+ char *isreexec = getenv(FUSE_MOUNTED_ENV);
- fd = fuse_mount_obsolete(&argc, argv);
- if(fd == -1)
- exit(1);
+ if(isreexec == NULL) {
+ if(argc < 2 || argv[1][0] == '-')
+ usage(argv[0]);
+
+ fuse_fd = fuse_mount(argv[1], NULL);
+ if(fuse_fd == -1)
+ exit(1);
+
+ argctr++;
+ }
+ else {
+ char *tmpstr;
+
+ /* Old (obsolescent) way of doing the mount:
+
+ fusermount [options] mountpoint [program [args ...]]
+
+ fusermount execs this program and passes the control file
+ descriptor dup()-ed to stdin */
+ fuse_fd = 0;
+
+ tmpstr = getenv(FUSE_UMOUNT_CMD_ENV);
+ if(tmpstr != NULL)
+ strncpy(umount_cmd, tmpstr, sizeof(umount_cmd) - 1);
+ }
atexit(fuse_unmount);
set_signal_handlers();
- argctr = 1;
flags = 0;
multithreaded = 1;
for(; argctr < argc && argv[argctr][0] == '-'; argctr ++) {
@@ -234,7 +246,7 @@ void fuse_main(int argc, char *argv[], const struct fuse_operations *op)
exit(1);
}
- fuse = fuse_new(fd, flags, op);
+ fuse = fuse_new(fuse_fd, flags, op);
if(multithreaded)
fuse_loop_mt(fuse);
diff --git a/makeconf.sh b/makeconf.sh
index 2c97050..8cd29ad 100755
--- a/makeconf.sh
+++ b/makeconf.sh
@@ -1,6 +1,12 @@
#! /bin/sh
+echo Running aclocal...
aclocal
+echo Running autoheader...
autoheader
+echo Running autoconf...
autoconf
+echo Running automake...
automake -a -c
+rm -f config.cache config.status
+echo "To compile run './configure', and then 'make'."
diff --git a/util/Makefile.am b/util/Makefile.am
index 0e4434f..48f9957 100644
--- a/util/Makefile.am
+++ b/util/Makefile.am
@@ -1,9 +1,8 @@
## Process this file with automake to produce Makefile.in
-bin_PROGRAMS = fusermount fuse_ioslave
+bin_PROGRAMS = fusermount
fusermount_SOURCES = fusermount.c
-fuse_ioslave_SOURCES = fuse_ioslave.c
install-exec-hook:
-chown root $(DESTDIR)$(bindir)/fusermount
diff --git a/util/fuse_ioslave.c b/util/fuse_ioslave.c
deleted file mode 100644
index df7c66d..0000000
--- a/util/fuse_ioslave.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <stdio.h> /* fprintf */
-#include <errno.h> /* errno */
-#include <string.h> /* strerror */
-#include <unistd.h> /* read,write,close */
-#include <stdlib.h> /* getenv,strtol */
-#include <sys/select.h> /* select */
-#include <sys/socket.h> /* send, recv */
-#include <sys/un.h> /* struct sockaddr_un */
-#define BUFSIZE (2<<16)
-#undef IOSLAVE_DEBUG
-char *scratch;
-
-/* return values:
- * 0 => success
- * -1 => error condition
- */
-int send_fd(int sock_fd, int send_fd) {
- int retval;
- struct msghdr msg;
- struct cmsghdr *p_cmsg;
- struct iovec vec;
- char cmsgbuf[CMSG_SPACE(sizeof(send_fd))];
- int *p_fds;
- char sendchar = 0;
- msg.msg_control = cmsgbuf;
- msg.msg_controllen = sizeof(cmsgbuf);
- p_cmsg = CMSG_FIRSTHDR(&msg);
- p_cmsg->cmsg_level = SOL_SOCKET;
- p_cmsg->cmsg_type = SCM_RIGHTS;
- p_cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd));
- p_fds = (int *) CMSG_DATA(p_cmsg);
- *p_fds = send_fd;
- msg.msg_controllen = p_cmsg->cmsg_len;
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &vec;
- msg.msg_iovlen = 1;
- msg.msg_flags = 0;
- /* "To pass file descriptors or credentials you need to send/read at
- * least one byte" (man 7 unix)
- */
- vec.iov_base = &sendchar;
- vec.iov_len = sizeof(sendchar);
- while((retval = sendmsg(sock_fd, &msg, 0)) == -1 && errno == EINTR);
- if (retval != 1) {
- perror("sendmsg");
- return -1;
- }
- return 0;
-}
-
-int main() {
- char *env = getenv("_FUSE_IOSLAVE_FD");
- int fd;
- if (!env)
- exit(fprintf(stderr, "fuse_ioslave: do not run me directly\n"));
- fd = strtol(env, NULL, 0);
- if(send_fd(fd, 0) == -1)
- fprintf(stderr,"failed to send fd\n");
- return 0;
-}
diff --git a/util/fusermount.c b/util/fusermount.c
index b3f46cf..ac464d2 100644
--- a/util/fusermount.c
+++ b/util/fusermount.c
@@ -29,6 +29,8 @@
#include <sys/stat.h>
#include <sys/mount.h>
#include <sys/fsuid.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#include <linux/fuse.h>
#define CHECK_PERMISSION 1
@@ -42,6 +44,7 @@
#define FUSE_MOUNTED_ENV "_FUSE_MOUNTED"
#define FUSE_UMOUNT_CMD_ENV "_FUSE_UNMOUNT_CMD"
#define FUSE_KERNEL_VERSION_ENV "_FUSE_KERNEL_VERSION"
+#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
const char *progname;
@@ -395,6 +398,42 @@ static char *resolve_path(const char *orig, int unmount)
return strdup(buf);
}
+static int send_fd(int sock_fd, int fd)
+{
+ int retval;
+ struct msghdr msg;
+ struct cmsghdr *p_cmsg;
+ struct iovec vec;
+ char cmsgbuf[CMSG_SPACE(sizeof(fd))];
+ int *p_fds;
+ char sendchar = 0;
+
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ p_cmsg = CMSG_FIRSTHDR(&msg);
+ p_cmsg->cmsg_level = SOL_SOCKET;
+ p_cmsg->cmsg_type = SCM_RIGHTS;
+ p_cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ p_fds = (int *) CMSG_DATA(p_cmsg);
+ *p_fds = fd;
+ msg.msg_controllen = p_cmsg->cmsg_len;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &vec;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+ /* "To pass file descriptors or credentials you need to send/read at
+ * least one byte" (man 7 unix) */
+ vec.iov_base = &sendchar;
+ vec.iov_len = sizeof(sendchar);
+ while((retval = sendmsg(sock_fd, &msg, 0)) == -1 && errno == EINTR);
+ if (retval != 1) {
+ perror("sending file descriptor");
+ return -1;
+ }
+ return 0;
+}
+
static void usage()
{
fprintf(stderr,
@@ -420,6 +459,7 @@ int main(int argc, char *argv[])
int numargs;
char mypath[PATH_MAX];
char *unmount_cmd;
+ char *commfd;
char verstr[128];
int flags = 0;
@@ -482,7 +522,9 @@ int main(int argc, char *argv[])
return 0;
}
- if(a == argc) {
+ commfd = getenv(FUSE_COMMFD_ENV);
+
+ if(a == argc && commfd == NULL) {
fprintf(stderr, "%s: Missing program argument\n", progname);
exit(1);
}
@@ -494,6 +536,14 @@ int main(int argc, char *argv[])
if(fd == -1)
exit(1);
+ if(commfd != NULL) {
+ int cfd = atoi(commfd);
+ res = send_fd(cfd, fd);
+ if(res == -1)
+ exit(1);
+ exit(0);
+ }
+
/* Dup the file descriptor to stdin */
if(fd != 0) {
dup2(fd, 0);