+2005-11-16 Miklos Szeredi <miklos@szeredi.hu>
+
+ * Merge library part of FreeBSD port. Patch by Csaba Henk
+
2005-11-11 Miklos Szeredi <miklos@szeredi.hu>
* Use 64bit type for file handle, so the full range supported by
doc/how-fuse-works \
doc/kernel.txt
-pkgconfigdir = $(libdir)/pkgconfig
+pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = fuse.pc
$(pkgconfig_DATA): config.status
AC_INIT(fuse, 2.5.0-pre0)
+AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(include/config.h)
AC_SUBST(mkdir_p)
fi
+case $target_os in
+ *linux*) arch=linux;;
+ *bsd*) arch=bsd;;
+ *) arch=unknown;;
+esac
+
if test "$ac_env_CFLAGS_set" != set; then
CFLAGS="-Wall -W -g -O2"
fi
AC_ARG_ENABLE(mtab,
[ --disable-mtab Disable and ignore usage of /etc/mtab ])
+AC_ARG_WITH(pkgconfigdir,
+ [ --with-pkgconfigdir=DIR pkgconfig file in DIR @<:@LIBDIR/pkgconfig@:>@],
+ [pkgconfigdir=$withval],
+ [pkgconfigdir='${libdir}/pkgconfig'])
+AC_SUBST(pkgconfigdir)
+
subdirs2="include"
-if test "$enable_kernel_module" != "no"; then
+if test "$arch" = linux -a "$enable_kernel_module" != "no"; then
AC_CONFIG_SUBDIRS(kernel)
fi
if test "$enable_lib" != "no"; then
subdirs2="$subdirs2 lib";
fi
-if test "$enable_util" != "no"; then
+if test "$arch" = linux -a "$enable_util" != "no"; then
subdirs2="$subdirs2 util";
fi
if test "$enable_example" != "no"; then
if test "$enable_mtab" = "no"; then
AC_DEFINE(IGNORE_MTAB, 1, [Don't update /etc/mtab])
fi
-AC_CHECK_FUNCS([fork setxattr])
+AC_CHECK_FUNCS([fork setxattr fdatasync])
AC_CHECK_MEMBERS([struct stat.st_atim])
if test -z "$MOUNT_FUSE_PATH"; then
AC_SUBST(subdirs2)
+AM_CONDITIONAL(LINUX, test "$arch" = linux)
+AM_CONDITIONAL(BSD, test "$arch" = bsd)
+
AC_CONFIG_FILES([fuse.pc Makefile lib/Makefile util/Makefile example/Makefile include/Makefile])
AC_OUTPUT
int res;
res = lstat(path, stbuf);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = access(path, mask);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = readlink(path, buf, size - 1);
- if(res == -1)
+ if (res == -1)
return -errno;
buf[res] = '\0';
(void) fi;
dp = opendir(path);
- if(dp == NULL)
+ if (dp == NULL)
return -errno;
- while((de = readdir(dp)) != NULL) {
+ while ((de = readdir(dp)) != NULL) {
struct stat st;
memset(&st, 0, sizeof(st));
st.st_ino = de->d_ino;
{
int res;
- res = mknod(path, mode, rdev);
- if(res == -1)
+ /* On Linux this could just be 'mknod(path, mode, rdev)' but this
+ is more portable */
+ if (S_ISREG(mode)) {
+ res = open(path, O_CREAT | O_EXCL | O_WRONLY, mode);
+ if (res >= 0)
+ res = close(res);
+ } else if (S_ISFIFO(mode))
+ res = mkfifo(path, mode);
+ else
+ res = mknod(path, mode, rdev);
+ if (res == -1)
return -errno;
return 0;
int res;
res = mkdir(path, mode);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = unlink(path);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = rmdir(path);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = symlink(from, to);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = rename(from, to);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = link(from, to);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = chmod(path, mode);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = lchown(path, uid, gid);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = truncate(path, size);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = utime(path, buf);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = open(path, fi->flags);
- if(res == -1)
+ if (res == -1)
return -errno;
close(res);
(void) fi;
fd = open(path, O_RDONLY);
- if(fd == -1)
+ if (fd == -1)
return -errno;
res = pread(fd, buf, size, offset);
- if(res == -1)
+ if (res == -1)
res = -errno;
close(fd);
(void) fi;
fd = open(path, O_WRONLY);
- if(fd == -1)
+ if (fd == -1)
return -errno;
res = pwrite(fd, buf, size, offset);
- if(res == -1)
+ if (res == -1)
res = -errno;
close(fd);
int res;
res = statvfs(path, stbuf);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
size_t size, int flags)
{
int res = lsetxattr(path, name, value, size, flags);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
}
size_t size)
{
int res = lgetxattr(path, name, value, size);
- if(res == -1)
+ if (res == -1)
return -errno;
return res;
}
static int xmp_listxattr(const char *path, char *list, size_t size)
{
int res = llistxattr(path, list, size);
- if(res == -1)
+ if (res == -1)
return -errno;
return res;
}
static int xmp_removexattr(const char *path, const char *name)
{
int res = lremovexattr(path, name);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
}
int res;
res = lstat(path, stbuf);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
(void) path;
res = fstat(fi->fh, stbuf);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = access(path, mask);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = readlink(path, buf, size - 1);
- if(res == -1)
+ if (res == -1)
return -errno;
buf[res] = '\0';
memset(&st, 0, sizeof(st));
st.st_ino = de->d_ino;
st.st_mode = de->d_type << 12;
- if (filler(buf, de->d_name, &st, de->d_off))
+ if (filler(buf, de->d_name, &st, telldir(dp)))
break;
}
{
int res;
- res = mknod(path, mode, rdev);
- if(res == -1)
+ if (S_ISFIFO(mode))
+ res = mkfifo(path, mode);
+ else
+ res = mknod(path, mode, rdev);
+ if (res == -1)
return -errno;
return 0;
int res;
res = mkdir(path, mode);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = unlink(path);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = rmdir(path);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = symlink(from, to);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = rename(from, to);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = link(from, to);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = chmod(path, mode);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = lchown(path, uid, gid);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = truncate(path, size);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
(void) path;
res = ftruncate(fi->fh, size);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
res = utime(path, buf);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int fd;
fd = open(path, fi->flags, mode);
- if(fd == -1)
+ if (fd == -1)
return -errno;
fi->fh = fd;
int fd;
fd = open(path, fi->flags);
- if(fd == -1)
+ if (fd == -1)
return -errno;
fi->fh = fd;
(void) path;
res = pread(fi->fh, buf, size, offset);
- if(res == -1)
+ if (res == -1)
res = -errno;
return res;
(void) path;
res = pwrite(fi->fh, buf, size, offset);
- if(res == -1)
+ if (res == -1)
res = -errno;
return res;
int res;
res = statvfs(path, stbuf);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
int res;
(void) path;
+#ifndef HAVE_FDATASYNC
+ (void) isdatasync;
+#else
if (isdatasync)
res = fdatasync(fi->fh);
else
+#endif
res = fsync(fi->fh);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
size_t size, int flags)
{
int res = lsetxattr(path, name, value, size, flags);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
}
size_t size)
{
int res = lgetxattr(path, name, value, size);
- if(res == -1)
+ if (res == -1)
return -errno;
return res;
}
static int xmp_listxattr(const char *path, char *list, size_t size)
{
int res = llistxattr(path, list, size);
- if(res == -1)
+ if (res == -1)
return -errno;
return res;
}
static int xmp_removexattr(const char *path, const char *name)
{
int res = lremovexattr(path, name);
- if(res == -1)
+ if (res == -1)
return -errno;
return 0;
}
/* This file defines the kernel interface of FUSE */
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#define __u64 uint64_t
+#define __u32 uint32_t
+#define __s32 int32_t
+#else
#include <asm/types.h>
+#endif
/** Version number of this interface */
#define FUSE_KERNEL_VERSION 7
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 \
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
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
+#include <fcntl.h>
#include <limits.h>
#include <errno.h>
#include <assert.h>
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);
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;
}
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 &&
else
fuse_instance = NULL;
- fuse_destroy(fuse);
fuse_unmount(mountpoint);
+ fuse_destroy(fuse);
free(mountpoint);
}
--- /dev/null
+/*
+ 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;
+}