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 | |
parent | 666aea72dfafcf8e93d9c781d1d8d3e644bd6949 (diff) | |
download | libfuse-b3f9972a859e95cf836c0044c82fcf312afc566e.tar.gz |
merge FreeBSD stuff
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 8 | ||||
-rw-r--r-- | lib/fuse.c | 21 | ||||
-rw-r--r-- | lib/fuse_lowlevel.c | 2 | ||||
-rw-r--r-- | lib/helper.c | 2 | ||||
-rw-r--r-- | lib/mount_bsd.c | 133 |
5 files changed, 162 insertions, 4 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index 8d340f9..0bd952e 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -2,6 +2,12 @@ lib_LTLIBRARIES = libfuse.la +if BSD +mount_source = mount_bsd.c +else +mount_source = mount.c +endif + libfuse_la_SOURCES = \ fuse.c \ fuse_i.h \ @@ -12,7 +18,7 @@ libfuse_la_SOURCES = \ fuse_mt.c \ fuse_session.c \ helper.c \ - mount.c + $(mount_source) libfuse_la_LDFLAGS = -lpthread -version-number 2:5:0 \ -Wl,--version-script,fuse_versionscript @@ -18,6 +18,7 @@ #include <string.h> #include <stdlib.h> #include <unistd.h> +#include <fcntl.h> #include <limits.h> #include <errno.h> #include <assert.h> @@ -804,7 +805,18 @@ static void fuse_mknod(fuse_req_t req, fuse_ino_t parent, const char *name, fflush(stdout); } err = -ENOSYS; - if (f->op.mknod && f->op.getattr) { + if (S_ISREG(mode) && f->op.create && f->op.getattr) { + struct fuse_file_info fi; + + memset(&fi, 0, sizeof(fi)); + fi.flags = O_CREAT | O_EXCL | O_WRONLY; + err = f->op.create(path, mode, &fi); + if (!err) { + err = lookup_path(f, parent, name, path, &e, &fi); + if (f->op.release) + f->op.release(path, &fi); + } + } else if (f->op.mknod && f->op.getattr) { err = f->op.mknod(path, mode, rdev); if (!err) err = lookup_path(f, parent, name, path, &e, NULL); @@ -1937,6 +1949,13 @@ static int parse_lib_opts(struct fuse *f, const char *opts, char **llopts) else free(xopts); } +#ifdef __FreeBSD__ + /* + * In FreeBSD, we always use these settings as inode numbers are needed to + * make getcwd(3) work. + */ + f->flags |= FUSE_READDIR_INO; +#endif return 0; } diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index f2ac121..31c2789 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -787,7 +787,7 @@ static void fuse_ll_process(void *data, const char *buf, size_t len, req->ch = ch; if (!f->got_init && in->opcode != FUSE_INIT) - fuse_reply_err(req, EPROTO); + fuse_reply_err(req, EIO); else if (f->allow_root && in->uid != f->owner && in->uid != 0 && in->opcode != FUSE_INIT && in->opcode != FUSE_READ && in->opcode != FUSE_WRITE && in->opcode != FUSE_FSYNC && diff --git a/lib/helper.c b/lib/helper.c index d8a522f..79616dc 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -381,8 +381,8 @@ void fuse_teardown(struct fuse *fuse, int fd, char *mountpoint) else fuse_instance = NULL; - fuse_destroy(fuse); fuse_unmount(mountpoint); + fuse_destroy(fuse); free(mountpoint); } 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; +} |