aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGravatar Nikolaus Rath <Nikolaus@rath.org>2016-10-02 11:30:43 -0700
committerGravatar Nikolaus Rath <Nikolaus@rath.org>2016-10-02 13:56:40 -0700
commit5698ee09cf7a8495da70659ffae1eaec9f57db27 (patch)
tree798a58a4f49d7f82e3f948463daad4405173483e /lib
parentf164e9b8ca319dd1279384ff495b5fa91e778d9e (diff)
Turn struct fuse_chan into an implementation detail
The only struct fuse_chan that's accessible to the user application is the "master" channel that is returned by fuse_mount and stored in struct fuse_session. When using the multi-threaded main loop with the "clone_fd" option, each worker thread gets its own struct fuse_chan. However, none of these are available to the user application, nor do they hold references to struct fuse_session (the pointer is always null). Therefore, any presence of struct fuse_chan can be removed without loss of functionality by relying on struct fuse_session instead. This reduces the number of API functions and removes a potential source of confusion (since the new API no longer looks as if it might be possible to add multiple channels to one session, or to share one channel between multiple sessions). Fixes issue #17.
Diffstat (limited to 'lib')
-rw-r--r--lib/fuse.c17
-rw-r--r--lib/fuse_i.h59
-rwxr-xr-xlib/fuse_lowlevel.c72
-rw-r--r--lib/fuse_versionscript5
-rw-r--r--lib/helper.c44
-rw-r--r--lib/mount.c98
-rw-r--r--lib/mount_bsd.c71
7 files changed, 217 insertions, 149 deletions
diff --git a/lib/fuse.c b/lib/fuse.c
index 47b72d0..bd7dc27 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -4631,7 +4631,7 @@ void fuse_stop_cleanup_thread(struct fuse *f)
}
}
-struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
+struct fuse *fuse_new(struct fuse_args *args,
const struct fuse_operations *op,
size_t op_size, void *user_data)
{
@@ -4721,13 +4721,13 @@ struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
or --version argument in `args` */
f->se = fuse_session_new(args, &llop, sizeof(llop), f);
if (f->se == NULL) {
+ /* If we've printed help before, add module help at
+ * the end */
if (f->conf.help)
fuse_lib_help_modules();
goto out_free_fs;
}
- fuse_session_add_chan(f->se, ch);
-
if (f->conf.debug) {
fprintf(stderr, "nopath: %i\n", f->conf.nopath);
}
@@ -4837,12 +4837,11 @@ void fuse_destroy(struct fuse *f)
fuse_delete_context_key();
}
-struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args)
-{
- return fuse_session_mount(mountpoint, args);
+int fuse_mount(struct fuse *f, const char *mountpoint) {
+ return fuse_session_mount(fuse_get_session(f), mountpoint);
}
-void fuse_unmount(const char *mountpoint, struct fuse_chan *ch)
-{
- fuse_session_unmount(mountpoint, ch);
+
+void fuse_unmount(struct fuse *f) {
+ return fuse_session_unmount(fuse_get_session(f));
}
diff --git a/lib/fuse_i.h b/lib/fuse_i.h
index dca588a..c4d0709 100644
--- a/lib/fuse_i.h
+++ b/lib/fuse_i.h
@@ -11,13 +11,16 @@
struct fuse_chan;
struct fuse_ll;
+struct mount_opts;
struct fuse_session {
struct fuse_ll *f;
+ char *mountpoint;
volatile int exited;
struct fuse_chan *ch;
+ struct mount_opts *mo;
};
struct fuse_chan {
@@ -116,7 +119,11 @@ struct fuse_module {
int fuse_chan_clearfd(struct fuse_chan *ch);
void fuse_chan_close(struct fuse_chan *ch);
-/**
+/* ----------------------------------------------------------- *
+ * Channel interface *
+ * ----------------------------------------------------------- */
+
+ /**
* Create a new channel
*
* @param op channel operations
@@ -133,8 +140,56 @@ struct fuse_chan *fuse_chan_new(int fd);
*/
struct fuse_session *fuse_chan_session(struct fuse_chan *ch);
+/**
+ * Remove the channel from a session
+ *
+ * If the channel is not assigned to a session, then this is a no-op
+ *
+ * @param ch the channel to remove
+ */
+void fuse_session_remove_chan(struct fuse_chan *ch);
+
+/**
+ * Assign a channel to a session
+ *
+ * If a session is destroyed, the assigned channel is also destroyed
+ *
+ * @param se the session
+ * @param ch the channel
+ */
+void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch);
+
+/**
+ * Return channel assigned to the session
+ *
+ * @param se the session
+ * @return the channel
+ */
+struct fuse_chan *fuse_session_chan(struct fuse_session *se);
+
+/**
+ * Obtain counted reference to the channel
+ *
+ * @param ch the channel
+ * @return the channel
+ */
+struct fuse_chan *fuse_chan_get(struct fuse_chan *ch);
+
+/**
+ * Drop counted reference to a channel
+ *
+ * @param ch the channel
+ */
+void fuse_chan_put(struct fuse_chan *ch);
+
+
+struct mount_opts *parse_mount_opts(struct fuse_args *args);
+void destroy_mount_opts(struct mount_opts *mo);
+void fuse_mount_help(void);
+void fuse_mount_version(void);
+
void fuse_kern_unmount(const char *mountpoint, int fd);
-int fuse_kern_mount(const char *mountpoint, struct fuse_args *args);
+int fuse_kern_mount(const char *mountpoint, struct mount_opts *mo);
int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov,
int count);
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index 92265cc..43539da 100755
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -2437,10 +2437,9 @@ static int fuse_ll_copy_from_pipe(struct fuse_bufvec *dst,
}
void fuse_session_process_buf(struct fuse_session *se,
- const struct fuse_buf *buf,
- struct fuse_chan *ch)
+ const struct fuse_buf *buf)
{
- fuse_session_process_buf_int(se, buf, ch);
+ fuse_session_process_buf_int(se, buf, se->ch);
}
void fuse_session_process_buf_int(struct fuse_session *se,
@@ -2666,15 +2665,17 @@ static void fuse_ll_help(void)
static int fuse_ll_opt_proc(void *data, const char *arg, int key,
struct fuse_args *outargs)
{
- (void) data; (void) outargs;
+ (void) data; (void) outargs; (void) arg;
switch (key) {
case KEY_HELP:
fuse_ll_help();
+ fuse_mount_help();
break;
case KEY_VERSION:
fuse_ll_version();
+ fuse_mount_version();
break;
default:
@@ -2706,6 +2707,7 @@ void fuse_session_destroy(struct fuse_session *se)
{
fuse_ll_destroy(se->f);
fuse_chan_put(se->ch);
+ destroy_mount_opts(se->mo);
free(se);
}
@@ -2716,10 +2718,9 @@ static void fuse_ll_pipe_destructor(void *data)
fuse_ll_pipe_free(llp);
}
-int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
- struct fuse_chan *ch)
+int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf)
{
- return fuse_session_receive_buf_int(se, buf, ch);
+ return fuse_session_receive_buf_int(se, buf, se->ch);
}
int fuse_session_receive_buf_int(struct fuse_session *se, struct fuse_buf *buf,
@@ -2878,6 +2879,7 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
int err;
struct fuse_ll *f;
struct fuse_session *se;
+ struct mount_opts *mo;
if (sizeof(struct fuse_lowlevel_ops) < op_size) {
fprintf(stderr, "fuse: warning: library too old, some operations may not work\n");
@@ -2890,6 +2892,16 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
goto out;
}
+ /* Parse options */
+ mo = parse_mount_opts(args);
+ if (mo == NULL)
+ goto out_free0;
+ if (fuse_opt_parse(args, f, fuse_ll_opts, fuse_ll_opt_proc) == -1)
+ goto out_free;
+
+ if (f->debug)
+ fprintf(stderr, "FUSE library version: %s\n", PACKAGE_VERSION);
+
f->conn.async_read = 1;
f->conn.max_write = UINT_MAX;
f->conn.max_readahead = UINT_MAX;
@@ -2910,12 +2922,6 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
goto out_free;
}
- if (fuse_opt_parse(args, f, fuse_ll_opts, fuse_ll_opt_proc) == -1)
- goto out_key_destroy;
-
- if (f->debug)
- fprintf(stderr, "FUSE library version: %s\n", PACKAGE_VERSION);
-
memcpy(&f->op, op, op_size);
f->owner = getuid();
f->userdata = userdata;
@@ -2927,19 +2933,21 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
}
memset(se, 0, sizeof(*se));
se->f = f;
+ se->mo = mo;
return se;
out_key_destroy:
pthread_key_delete(f->pipe_key);
out_free:
+ free(mo);
+out_free0:
pthread_mutex_destroy(&f->lock);
free(f);
out:
return NULL;
}
-struct fuse_chan *fuse_session_mount(const char *mountpoint,
- struct fuse_args *args)
+int fuse_session_mount(struct fuse_session *se, const char *mountpoint)
{
struct fuse_chan *ch;
int fd;
@@ -2954,23 +2962,39 @@ struct fuse_chan *fuse_session_mount(const char *mountpoint,
close(fd);
} while (fd >= 0 && fd <= 2);
- fd = fuse_kern_mount(mountpoint, args);
+ /* Open channel */
+ fd = fuse_kern_mount(mountpoint, se->mo);
if (fd == -1)
- return NULL;
+ return -1;
ch = fuse_chan_new(fd);
if (!ch)
- fuse_kern_unmount(mountpoint, fd);
+ goto error_out;
+
+ /* Add channel to session */
+ fuse_session_add_chan(se, ch);
- return ch;
+ /* Save mountpoint */
+ se->mountpoint = strdup(mountpoint);
+ if (se->mountpoint == NULL)
+ goto error_out;
+
+ return 0;
+
+error_out:
+ fuse_kern_unmount(mountpoint, fd);
+ return -1;
}
-void fuse_session_unmount(const char *mountpoint, struct fuse_chan *ch)
+void fuse_session_unmount(struct fuse_session *se)
{
- if (mountpoint) {
- int fd = ch ? fuse_chan_clearfd(ch) : -1;
- fuse_kern_unmount(mountpoint, fd);
- fuse_chan_put(ch);
+ fuse_session_remove_chan(se->ch);
+ if (se->mountpoint) {
+ int fd = se->ch ? fuse_chan_clearfd(se->ch) : -1;
+ fuse_kern_unmount(se->mountpoint, fd);
+ fuse_chan_put(se->ch);
+ free(se->mountpoint);
+ se->mountpoint = NULL;
}
}
diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
index eacd37a..ee9c9d7 100644
--- a/lib/fuse_versionscript
+++ b/lib/fuse_versionscript
@@ -4,8 +4,6 @@ FUSE_3.0 {
fuse_exit;
fuse_loop;
fuse_loop_mt;
- fuse_chan_destroy;
- fuse_chan_fd;
fuse_reply_attr;
fuse_reply_buf;
fuse_reply_entry;
@@ -15,13 +13,11 @@ FUSE_3.0 {
fuse_reply_write;
fuse_reply_xattr;
fuse_req_userdata;
- fuse_session_add_chan;
fuse_session_destroy;
fuse_session_exit;
fuse_session_exited;
fuse_session_loop;
fuse_session_loop_mt;
- fuse_session_chan;
fuse_session_reset;
fuse_opt_parse;
fuse_opt_add_opt;
@@ -48,7 +44,6 @@ FUSE_3.0 {
fuse_reply_lock;
fuse_req_interrupt_func;
fuse_req_interrupted;
- fuse_session_remove_chan;
fuse_unmount;
fuse_session_unmount;
fuse_fs_access;
diff --git a/lib/helper.c b/lib/helper.c
index cd1a54b..7ee767b 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -227,30 +227,32 @@ int fuse_daemonize(int foreground)
return 0;
}
+
static struct fuse *fuse_setup(int argc, char *argv[],
- const struct fuse_operations *op, size_t op_size,
- char **mountpoint, int *multithreaded, void *user_data)
+ const struct fuse_operations *op, size_t op_size,
+ int *multithreaded, void *user_data)
{
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
- struct fuse_chan *ch;
struct fuse *fuse;
+ char *mountpoint;
int foreground;
int res;
- res = fuse_parse_cmdline(&args, mountpoint, multithreaded, &foreground);
+ res = fuse_parse_cmdline(&args, &mountpoint, multithreaded, &foreground);
if (res == -1)
return NULL;
- ch = fuse_mount(*mountpoint, &args);
- if (!ch) {
+ fuse = fuse_new(&args, op, op_size, user_data);
+ if (fuse == NULL) {
fuse_opt_free_args(&args);
- goto err_free;
+ free(mountpoint);
+ return NULL;
}
- fuse = fuse_new(ch, &args, op, op_size, user_data);
- fuse_opt_free_args(&args);
- if (fuse == NULL)
- goto err_unmount;
+ res = fuse_mount(fuse, mountpoint);
+ free(mountpoint);
+ if (res != 0)
+ goto err_out1;
res = fuse_daemonize(foreground);
if (res == -1)
@@ -263,33 +265,29 @@ static struct fuse *fuse_setup(int argc, char *argv[],
return fuse;
err_unmount:
- fuse_unmount(*mountpoint, ch);
- if (fuse)
- fuse_destroy(fuse);
-err_free:
- free(*mountpoint);
+ fuse_unmount(fuse);
+err_out1:
+ fuse_destroy(fuse);
+ fuse_opt_free_args(&args);
return NULL;
}
-static void fuse_teardown(struct fuse *fuse, char *mountpoint)
+static void fuse_teardown(struct fuse *fuse)
{
struct fuse_session *se = fuse_get_session(fuse);
- struct fuse_chan *ch = fuse_session_chan(se);
fuse_remove_signal_handlers(se);
- fuse_unmount(mountpoint, ch);
+ fuse_unmount(fuse);
fuse_destroy(fuse);
- free(mountpoint);
}
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
size_t op_size, void *user_data)
{
struct fuse *fuse;
- char *mountpoint;
int multithreaded;
int res;
- fuse = fuse_setup(argc, argv, op, op_size, &mountpoint,
+ fuse = fuse_setup(argc, argv, op, op_size,
&multithreaded, user_data);
if (fuse == NULL)
return 1;
@@ -299,7 +297,7 @@ int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
else
res = fuse_loop(fuse);
- fuse_teardown(fuse, mountpoint);
+ fuse_teardown(fuse);
if (res == -1)
return 1;
diff --git a/lib/mount.c b/lib/mount.c
index b2b841d..fb17c00 100644
--- a/lib/mount.c
+++ b/lib/mount.c
@@ -57,14 +57,11 @@ enum {
KEY_MTAB_OPT,
KEY_ALLOW_ROOT,
KEY_RO,
- KEY_HELP,
- KEY_VERSION,
};
struct mount_opts {
int allow_other;
int allow_root;
- int ishelp;
int flags;
int nonempty;
int auto_unmount;
@@ -118,14 +115,10 @@ static const struct fuse_opt fuse_mount_opts[] = {
FUSE_OPT_KEY("dirsync", KEY_KERN_FLAG),
FUSE_OPT_KEY("atime", KEY_KERN_FLAG),
FUSE_OPT_KEY("noatime", KEY_KERN_FLAG),
- FUSE_OPT_KEY("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("-V", KEY_VERSION),
- FUSE_OPT_KEY("--version", KEY_VERSION),
FUSE_OPT_END
};
-static void mount_help(void)
+void fuse_mount_help(void)
{
printf(
" -o allow_other allow access to other users\n"
@@ -146,7 +139,7 @@ static void exec_fusermount(const char *argv[])
execvp(FUSERMOUNT_PROG, (char **) argv);
}
-static void mount_version(void)
+void fuse_mount_version(void)
{
int pid = fork();
if (!pid) {
@@ -230,16 +223,6 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key,
case KEY_MTAB_OPT:
return fuse_opt_add_opt(&mo->mtab_opts, arg);
-
- case KEY_HELP:
- mount_help();
- mo->ishelp = 1;
- break;
-
- case KEY_VERSION:
- mount_version();
- mo->ishelp = 1;
- break;
}
/* Pass through unknown options */
@@ -568,67 +551,84 @@ static int get_mnt_flag_opts(char **mnt_optsp, int flags)
return 0;
}
-int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
+struct mount_opts *parse_mount_opts(struct fuse_args *args)
{
- struct mount_opts mo;
- int res = -1;
- char *mnt_opts = NULL;
+ struct mount_opts *mo;
+
+ mo = (struct mount_opts*) malloc(sizeof(struct mount_opts));
+ if (mo == NULL)
+ return NULL;
- memset(&mo, 0, sizeof(mo));
- mo.flags = MS_NOSUID | MS_NODEV;
+ memset(mo, 0, sizeof(struct mount_opts));
+ mo->flags = MS_NOSUID | MS_NODEV;
if (args &&
- fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
- return -1;
+ fuse_opt_parse(args, mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
+ goto err_out;
- if (mo.allow_other && mo.allow_root) {
+ if (mo->allow_other && mo->allow_root) {
fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
- goto out;
+ goto err_out;
}
- res = 0;
- if (mo.ishelp)
- goto out;
+
+ return mo;
+
+err_out:
+ destroy_mount_opts(mo);
+ return NULL;
+}
+
+void destroy_mount_opts(struct mount_opts *mo)
+{
+ free(mo->fsname);
+ free(mo->subtype);
+ free(mo->fusermount_opts);
+ free(mo->subtype_opt);
+ free(mo->kernel_opts);
+ free(mo->mtab_opts);
+ free(mo);
+}
+
+
+int fuse_kern_mount(const char *mountpoint, struct mount_opts *mo)
+{
+ int res = -1;
+ char *mnt_opts = NULL;
res = -1;
- if (get_mnt_flag_opts(&mnt_opts, mo.flags) == -1)
+ if (get_mnt_flag_opts(&mnt_opts, mo->flags) == -1)
goto out;
- if (mo.kernel_opts && fuse_opt_add_opt(&mnt_opts, mo.kernel_opts) == -1)
+ if (mo->kernel_opts && fuse_opt_add_opt(&mnt_opts, mo->kernel_opts) == -1)
goto out;
- if (mo.mtab_opts && fuse_opt_add_opt(&mnt_opts, mo.mtab_opts) == -1)
+ if (mo->mtab_opts && fuse_opt_add_opt(&mnt_opts, mo->mtab_opts) == -1)
goto out;
- res = fuse_mount_sys(mountpoint, &mo, mnt_opts);
+ res = fuse_mount_sys(mountpoint, mo, mnt_opts);
if (res == -2) {
- if (mo.fusermount_opts &&
- fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) == -1)
+ if (mo->fusermount_opts &&
+ fuse_opt_add_opt(&mnt_opts, mo->fusermount_opts) == -1)
goto out;
- if (mo.subtype) {
+ if (mo->subtype) {
char *tmp_opts = NULL;
res = -1;
if (fuse_opt_add_opt(&tmp_opts, mnt_opts) == -1 ||
- fuse_opt_add_opt(&tmp_opts, mo.subtype_opt) == -1) {
+ fuse_opt_add_opt(&tmp_opts, mo->subtype_opt) == -1) {
free(tmp_opts);
goto out;
}
- res = fuse_mount_fusermount(mountpoint, &mo, tmp_opts, 1);
+ res = fuse_mount_fusermount(mountpoint, mo, tmp_opts, 1);
free(tmp_opts);
if (res == -1)
- res = fuse_mount_fusermount(mountpoint, &mo,
+ res = fuse_mount_fusermount(mountpoint, mo,
mnt_opts, 0);
} else {
- res = fuse_mount_fusermount(mountpoint, &mo, mnt_opts, 0);
+ res = fuse_mount_fusermount(mountpoint, mo, mnt_opts, 0);
}
}
out:
free(mnt_opts);
- free(mo.fsname);
- free(mo.subtype);
- free(mo.fusermount_opts);
- free(mo.subtype_opt);
- free(mo.kernel_opts);
- free(mo.mtab_opts);
return res;
}
diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c
index 40ef93f..0d886b0 100644
--- a/lib/mount_bsd.c
+++ b/lib/mount_bsd.c
@@ -31,15 +31,12 @@
enum {
KEY_ALLOW_ROOT,
KEY_RO,
- KEY_HELP,
- KEY_VERSION,
KEY_KERN
};
struct mount_opts {
int allow_other;
int allow_root;
- int ishelp;
char *kernel_opts;
};
@@ -51,10 +48,6 @@ static const struct fuse_opt fuse_mount_opts[] = {
{ "allow_root", offsetof(struct mount_opts, allow_root), 1 },
FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
FUSE_OPT_KEY("-r", KEY_RO),
- FUSE_OPT_KEY("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("-V", KEY_VERSION),
- FUSE_OPT_KEY("--version", KEY_VERSION),
/* standard FreeBSD mount options */
FUSE_DUAL_OPT_KEY("dev", KEY_KERN),
FUSE_DUAL_OPT_KEY("async", KEY_KERN),
@@ -100,14 +93,14 @@ static const struct fuse_opt fuse_mount_opts[] = {
FUSE_OPT_END
};
-static void mount_help(void)
+void fuse_mount_help(void)
{
printf(" -o allow_root allow access to root\n");
system(FUSERMOUNT_PROG " --help");
fputc('\n', stderr);
}
-static void mount_version(void)
+void fuse_mount_version(void)
{
system(FUSERMOUNT_PROG " --version");
}
@@ -130,16 +123,6 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key,
case KEY_KERN:
return fuse_opt_add_opt(&mo->kernel_opts, arg);
-
- case KEY_HELP:
- mount_help();
- mo->ishelp = 1;
- break;
-
- case KEY_VERSION:
- mount_version();
- mo->ishelp = 1;
- break;
}
/* Pass through unknown options */
@@ -314,30 +297,44 @@ out:
return fd;
}
-int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
+struct mount_opts *parse_mount_opts(struct fuse_args *args)
{
- struct mount_opts mo;
- int res = -1;
+ struct mount_opts *mo;
- memset(&mo, 0, sizeof(mo));
- /* mount util should not try to spawn the daemon */
- setenv("MOUNT_FUSEFS_SAFE", "1", 1);
- /* to notify the mount util it's called from lib */
- setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1);
+ mo = (struct mount_opts*) malloc(sizeof(struct mount_opts));
+ if (mo == NULL)
+ return NULL;
+
+ memset(mo, 0, sizeof(struct mount_opts));
if (args &&
- fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
- return -1;
+ fuse_opt_parse(args, mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
+ goto err_out;
- if (mo.allow_other && mo.allow_root) {
+ if (mo->allow_other && mo->allow_root) {
fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
- goto out;
+ goto err_out;
}
- if (mo.ishelp)
- return 0;
- res = fuse_mount_core(mountpoint, mo.kernel_opts);
-out:
- free(mo.kernel_opts);
- return res;
+ return mo;
+
+err_out:
+ destroy_mount_opts(mo);
+ return NULL;
+}
+
+void destroy_mount_opts(struct mount_opts *mo)
+{
+ free(mo->kernel_opts);
+ free(mo);
+}
+
+int fuse_kern_mount(const char *mountpoint, struct mount_opts *mo)
+{
+ /* mount util should not try to spawn the daemon */
+ setenv("MOUNT_FUSEFS_SAFE", "1", 1);
+ /* to notify the mount util it's called from lib */
+ setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1);
+
+ return fuse_mount_core(mountpoint, mo->kernel_opts);
}