diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile | 8 | ||||
-rw-r--r-- | lib/fuse.c | 41 | ||||
-rw-r--r-- | lib/fuse_i.h | 3 | ||||
-rw-r--r-- | lib/mount.c | 22 |
4 files changed, 51 insertions, 23 deletions
diff --git a/lib/Makefile b/lib/Makefile index e72a39d..88b087a 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,16 +1,18 @@ CC = gcc -CFLAGS = -Wall -W -g `glib-config --cflags` +CFLAGS = -Wall -W -g `glib-config --cflags` -fPIC LDFLAGS = `glib-config --libs` CPPFLAGS = -I../include - -all: libfuse.a +all: libfuse.a libfuse.so libfuse_objs = mount.o fuse.o libfuse.a: $(libfuse_objs) ar cr libfuse.a $(libfuse_objs) +libfuse.so: $(libfuse_objs) + gcc -shared -o libfuse.so $(libfuse_objs) + clean: rm -f *.o *.a rm -f *~ @@ -407,6 +407,7 @@ static void do_readlink(struct fuse *f, struct fuse_in_header *in) res = f->op.readlink(&cred, path, link, sizeof(link)); g_free(path); } + link[PATH_MAX] = '\0'; send_reply(f, in, res, link, !res ? strlen(link) : 0); } @@ -756,6 +757,17 @@ static void *do_command(void *data) return NULL; } +/* This hack makes it possible to link FUSE with or without the + pthread library */ +__attribute__((weak)) +int pthread_create(pthread_t *thrid __attribute__((unused)), + const pthread_attr_t *attr __attribute__((unused)), + void *(*func)(void *) __attribute__((unused)), + void *arg __attribute__((unused))) +{ + return ENOSYS; +} + void fuse_loop(struct fuse *f) { int res; @@ -787,24 +799,35 @@ void fuse_loop(struct fuse *f) if(f->flags & FUSE_MULTITHREAD) { res = pthread_create(&thrid, &attr, do_command, cmd); - if(res != 0) { - fprintf(stderr, "Error creating thread: %s\n", - strerror(errno)); - exit(1); - } + if(res == 0) + continue; + + fprintf(stderr, "Error creating thread: %s\n", strerror(res)); + fprintf(stderr, "Will run in single thread mode\n"); + f->flags &= ~FUSE_MULTITHREAD; } - else - do_command(cmd); + + do_command(cmd); } } -struct fuse *fuse_new(int flags) +struct fuse *fuse_new(int flags, mode_t root) { struct fuse *f = g_new0(struct fuse, 1); + if(!root) + root = S_IFDIR; + + if(!S_ISDIR(root) && !S_ISREG(root)) { + fprintf(stderr, "Invalid mode for root: 0%o\n", root); + root = S_IFDIR; + } + root &= S_IFMT; + f->flags = flags; + f->rootmode = root; f->fd = -1; - f->dir = NULL; + f->mnt = NULL; f->nametab = g_hash_table_new((GHashFunc) name_hash, (GCompareFunc) name_compare); pthread_mutex_init(&f->lock, NULL); diff --git a/lib/fuse_i.h b/lib/fuse_i.h index c28e2e8..6f363d8 100644 --- a/lib/fuse_i.h +++ b/lib/fuse_i.h @@ -25,7 +25,8 @@ struct node { struct fuse { int flags; - char *dir; + char *mnt; + mode_t rootmode; int fd; struct fuse_operations op; GHashTable *nametab; diff --git a/lib/mount.c b/lib/mount.c index 48d9d45..98d9e59 100644 --- a/lib/mount.c +++ b/lib/mount.c @@ -16,13 +16,15 @@ #include <sys/mount.h> #include <mntent.h> -static int do_mount(const char *dev, const char *dir, const char *type, int fd) +static int do_mount(const char *dev, const char *dir, const char *type, + mode_t rootmode, int fd) { int res; struct fuse_mount_data data; - data.version = FUSE_MOUNT_VERSION; + data.version = FUSE_KERNEL_VERSION; data.fd = fd; + data.rootmode = rootmode; res = mount(dev, dir, type, MS_MGC_VAL | MS_NOSUID | MS_NODEV, &data); if(res == -1) { @@ -100,7 +102,7 @@ int fuse_mount(struct fuse *f, const char *dir) const char *dev = FUSE_DEV; const char *type = "fuse"; - if(f->dir != NULL) + if(f->mnt != NULL) return 0; f->fd = open(dev, O_RDWR); @@ -109,12 +111,12 @@ int fuse_mount(struct fuse *f, const char *dir) return -1; } - res = do_mount(dev, dir, type, f->fd); + res = do_mount(dev, dir, type, f->rootmode, f->fd); if(res == -1) return -1; add_mntent(dev, dir, type); - f->dir = g_strdup(dir); + f->mnt = g_strdup(dir); return 0; } @@ -123,20 +125,20 @@ int fuse_unmount(struct fuse *f) { int res; - if(f->dir == NULL) + if(f->mnt == NULL) return 0; close(f->fd); f->fd = -1; - res = umount(f->dir); + res = umount(f->mnt); if(res == -1) perror("umount failed"); else - remove_mntent(f->dir); + remove_mntent(f->mnt); - g_free(f->dir); - f->dir = NULL; + g_free(f->mnt); + f->mnt = NULL; return res; } |