+2006-03-17 Miklos Szeredi <miklos@szeredi.hu>
+
+ * API changes:
+
+ * fuse_main(), fuse_setup() and fuse_new() have an additionl
+ user_data parameter
+
+ * fuse_mount() returns a 'struct fuse_chan' pointer instead of a
+ file descriptor
+
+ * fuse_unmount() receives a 'struct fuse_chan' pointer. It
+ destroys the given channel
+
+ * fuse_teardown() no longer has a file descriptor parameter
+
+ * new exported functions: fuse_session_remove_chan(),
+ fuse_get_session(), fuse_daemonize()
+
2006-03-16 Miklos Szeredi <miklos@szeredi.hu>
* Released 2.6.0-pre2
int main(int argc, char *argv[])
{
umask(0);
- return fuse_main(argc, argv, &xmp_oper);
+ return fuse_main(argc, argv, &xmp_oper, NULL);
}
int main(int argc, char *argv[])
{
umask(0);
- return fuse_main(argc, argv, &xmp_oper);
+ return fuse_main(argc, argv, &xmp_oper, NULL);
}
int main(int argc, char *argv[])
{
- return fuse_main(argc, argv, &hello_oper);
+ return fuse_main(argc, argv, &hello_oper, NULL);
}
int main(int argc, char *argv[])
{
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
+ struct fuse_chan *ch;
char *mountpoint;
int err = -1;
- int fd = -1;
if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
- (fd = fuse_mount(mountpoint, &args)) != -1) {
+ (ch = fuse_mount(mountpoint, &args)) != NULL) {
struct fuse_session *se;
se = fuse_lowlevel_new(&args, &hello_ll_oper, sizeof(hello_ll_oper),
NULL);
if (se != NULL) {
if (fuse_set_signal_handlers(se) != -1) {
- struct fuse_chan *ch = fuse_kern_chan_new(fd);
- if (ch != NULL) {
- fuse_session_add_chan(se, ch);
- err = fuse_session_loop(se);
- }
+ fuse_session_add_chan(se, ch);
+ err = fuse_session_loop(se);
fuse_remove_signal_handlers(se);
+ fuse_session_remove_chan(ch);
}
- fuse_unmount(mountpoint, fd);
fuse_session_destroy(se);
- goto out;
}
- close(fd);
+ fuse_unmount(mountpoint, ch);
}
- fuse_unmount(mountpoint, fd);
-out:
fuse_opt_free_args(&args);
return err ? 1 : 0;
int main(int argc, char *argv[])
{
- return fuse_main(argc, argv, &null_oper);
+ return fuse_main(argc, argv, &null_oper, NULL);
}
* @param argc the argument counter passed to the main() function
* @param argv the argument vector passed to the main() function
* @param op the file system operation
+ * @param user_data user data set in context for init() method
* @return 0 on success, nonzero on failure
*/
/*
-int fuse_main(int argc, char *argv[], const struct fuse_operations *op);
+int fuse_main(int argc, char *argv[], const struct fuse_operations *op,
+ void *user_data);
*/
-#define fuse_main(argc, argv, op) \
- fuse_main_real(argc, argv, op, sizeof(*(op)))
+#define fuse_main(argc, argv, op, user_data) \
+ fuse_main_real(argc, argv, op, sizeof(*(op)), user_data)
/* ----------------------------------------------------------- *
* More detailed API *
/**
* Create a new FUSE filesystem.
*
- * @param fd the control file descriptor
+ * @param ch the communication channel
* @param args argument vector
* @param op the operations
* @param op_size the size of the fuse_operations structure
+ * @param user_data user data set in context for init() method
* @return the created FUSE handle
*/
-struct fuse *fuse_new(int fd, struct fuse_args *args,
- const struct fuse_operations *op, size_t op_size);
+struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
+ const struct fuse_operations *op, size_t op_size,
+ void *user_data);
/**
* Destroy the FUSE handle.
* Do not call this directly, use fuse_main()
*/
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
- size_t op_size);
+ size_t op_size, void *user_data);
/* ----------------------------------------------------------- *
* Advanced API for event handling, don't worry about this... *
/** This is the part of fuse_main() before the event loop */
struct fuse *fuse_setup(int argc, char *argv[],
const struct fuse_operations *op, size_t op_size,
- char **mountpoint, int *multithreaded, int *fd);
+ char **mountpoint, int *multithreaded,
+ void *user_data);
/** This is the part of fuse_main() after the event loop */
-void fuse_teardown(struct fuse *fuse, int fd, char *mountpoint);
+void fuse_teardown(struct fuse *fuse, char *mountpoint);
/** Read a single command. If none are read, return NULL */
struct fuse_cmd *fuse_read_cmd(struct fuse *f);
/** Set function which can be used to get the current context */
void fuse_set_getcontext_func(struct fuse_context *(*func)(void));
+/** Get session from fuse object */
+struct fuse_session *fuse_get_session(struct fuse *f);
+
/* ----------------------------------------------------------- *
* Compatibility stuff *
* ----------------------------------------------------------- */
fuse_main_real_compat25(argc, argv, op, sizeof(*(op)))
# define fuse_new fuse_new_compat25
# define fuse_setup fuse_setup_compat25
+# define fuse_teardown fuse_teardown_compat25
# define fuse_operations fuse_operations_compat25
# elif FUSE_USE_VERSION == 22
# define fuse_main(argc, argv, op) \
unsigned reserved[27];
};
+struct fuse_session;
+struct fuse_chan;
+
/**
* Create a FUSE mountpoint
*
*
* @param mountpoint the mount point path
* @param args argument vector
- * @return the control file descriptor on success, -1 on failure
+ * @return the communication channel on success, NULL on failure
*/
-int fuse_mount(const char *mountpoint, struct fuse_args *args);
+struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args);
/**
* Umount a FUSE mountpoint
*
* @param mountpoint the mount point path
- * @param the control file descriptor
+ * @param ch the communication channel
*/
-void fuse_unmount(const char *mountpoint, int fd);
+void fuse_unmount(const char *mountpoint, struct fuse_chan *ch);
/**
* Parse common options
int *multithreaded, int *foreground);
+int fuse_daemonize(int foreground);
+
+/* ----------------------------------------------------------- *
+ * Signal handling *
+ * ----------------------------------------------------------- */
+
+/**
+ * Exit session on HUP, TERM and INT signals and ignore PIPE signal
+ *
+ * Stores session in a global variable. May only be called once per
+ * process until fuse_remove_signal_handlers() is called.
+ *
+ * @param se the session to exit
+ * @return 0 on success, -1 on failure
+ */
+int fuse_set_signal_handlers(struct fuse_session *se);
+
+/**
+ * Restore default signal handlers
+ *
+ * Resets global session. After this fuse_set_signal_handlers() may
+ * be called again.
+ *
+ * @param se the same session as given in fuse_set_signal_handlers()
+ */
+void fuse_remove_signal_handlers(struct fuse_session *se);
+
+/* ----------------------------------------------------------- *
+ * Compatibility stuff *
+ * ----------------------------------------------------------- */
+
#if FUSE_USE_VERSION < 26
# ifdef __FreeBSD__
# if FUSE_USE_VERSION < 25
# include "fuse_common_compat.h"
# undef FUSE_MINOR_VERSION
# undef fuse_main
+# define fuse_mount fuse_mount_compat25
# define fuse_unmount fuse_unmount_compat22
# if FUSE_USE_VERSION == 25
# define FUSE_MINOR_VERSION 5
/* these definitions provide source compatibility to prior versions.
Do not include this file directly! */
+int fuse_mount_compat25(const char *mountpoint, struct fuse_args *args);
+
int fuse_mount_compat22(const char *mountpoint, const char *opts);
int fuse_mount_compat1(const char *mountpoint, const char *args[]);
size_t op_size, char **mountpoint,
int *multithreaded, int *fd);
+void fuse_teardown_compat25(struct fuse *fuse, int fd, char *mountpoint);
+
#ifndef __FreeBSD__
#include <sys/statfs.h>
const struct fuse_lowlevel_ops *op,
size_t op_size, void *userdata);
-/**
- * Create a kernel channel
- *
- * @param fd the file descriptor obtained from fuse_mount()
- * @return the created channel object, or NULL on failure
- */
-struct fuse_chan *fuse_kern_chan_new(int fd);
-
/* ----------------------------------------------------------- *
* Session interface *
* ----------------------------------------------------------- */
*/
void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch);
+/**
+ * Remove a 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);
+
/**
* Iterate over the channels assigned to a session
*
*/
void fuse_chan_destroy(struct fuse_chan *ch);
-/* ----------------------------------------------------------- *
- * Signal handling *
- * ----------------------------------------------------------- */
-
-/**
- * Exit session on HUP, TERM and INT signals and ignore PIPE signal
- *
- * Stores session in a global variable. May only be called once per
- * process until fuse_remove_signal_handlers() is called.
- *
- * @param se the session to exit
- * @return 0 on success, -1 on failure
- */
-int fuse_set_signal_handlers(struct fuse_session *se);
-
-/**
- * Restore default signal handlers
- *
- * Resets global session. After this fuse_set_signal_handlers() may
- * be called again.
- *
- * @param se the same session as given in fuse_set_signal_handlers()
- */
-void fuse_remove_signal_handlers(struct fuse_session *se);
-
/* ----------------------------------------------------------- *
* Compatibility stuff *
* ----------------------------------------------------------- */
memset(c, 0, sizeof(*c));
c->fuse = f;
+ c->private_data = f->user_data;
if (f->op.init)
f->user_data = f->op.init(conn);
fuse_opt_match(fuse_lib_opts, opt);
}
-struct fuse *fuse_new_common(int fd, struct fuse_args *args,
+struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
const struct fuse_operations *op,
- size_t op_size, int compat)
+ size_t op_size, void *user_data, int compat)
{
- struct fuse_chan *ch;
struct fuse *f;
struct node *root;
goto out;
}
+ f->user_data = user_data;
f->conf.entry_timeout = 1.0;
f->conf.attr_timeout = 1.0;
f->conf.negative_timeout = 0.0;
if (f->se == NULL)
goto out_free;
- ch = fuse_kern_chan_new(fd);
- if (ch == NULL)
- goto out_free_session;
-
fuse_session_add_chan(f->se, ch);
f->ctr = 0;
return NULL;
}
-struct fuse *fuse_new(int fd, struct fuse_args *args,
- const struct fuse_operations *op, size_t op_size)
+struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
+ const struct fuse_operations *op, size_t op_size,
+ void *user_data)
{
- return fuse_new_common(fd, args, op, op_size, 0);
+ return fuse_new_common(ch, args, op, op_size, user_data, 0);
}
void fuse_destroy(struct fuse *f)
#include "fuse_compat.h"
+static struct fuse *fuse_new_common_compat25(int fd, struct fuse_args *args,
+ const struct fuse_operations *op,
+ size_t op_size, int compat)
+{
+ struct fuse *f = NULL;
+ struct fuse_chan *ch = fuse_kern_chan_new(fd);
+
+ if (ch)
+ f = fuse_new_common(ch, args, op, op_size, NULL, compat);
+
+ return f;
+}
+
#ifndef __FreeBSD__
static int fuse_do_open(struct fuse *f, char *path, struct fuse_file_info *fi)
fuse_opt_free_args(&args);
return NULL;
}
- f = fuse_new_common(fd, &args, op, op_size, compat);
+ f = fuse_new_common_compat25(fd, &args, op, op_size, compat);
fuse_opt_free_args(&args);
return f;
const struct fuse_operations_compat25 *op,
size_t op_size)
{
- return fuse_new_common(fd, args, (struct fuse_operations *) op,
- op_size, 25);
+ return fuse_new_common_compat25(fd, args, (struct fuse_operations *) op,
+ op_size, 25);
}
__asm__(".symver fuse_new_compat25,fuse_new@FUSE_2.5");
struct fuse_chan *ch;
};
-struct fuse_session *fuse_get_session(struct fuse *f);
-
-struct fuse *fuse_new_common(int fd, struct fuse_args *args,
+struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
const struct fuse_operations *op,
- size_t op_size, int compat);
+ size_t op_size, void *user_data, int compat);
int fuse_sync_compat_args(struct fuse_args *args);
+struct fuse_chan *fuse_kern_chan_new(int fd);
+
struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args,
const struct fuse_lowlevel_ops *op,
size_t op_size, void *userdata);
+
+void fuse_kern_unmount_compat22(const char *mountpoint);
+void fuse_kern_unmount(const char *mountpoint, int fd);
+int fuse_kern_mount(const char *mountpoint, struct fuse_args *args);
ch->se = se;
}
+void fuse_session_remove_chan(struct fuse_chan *ch)
+{
+ struct fuse_session *se = ch->se;
+ if (se) {
+ assert(se->ch == ch);
+ se->ch = NULL;
+ ch->se = NULL;
+ }
+}
+
struct fuse_chan *fuse_session_next_chan(struct fuse_session *se,
struct fuse_chan *ch)
{
void fuse_chan_destroy(struct fuse_chan *ch)
{
+ fuse_session_remove_chan(ch);
if (ch->op.destroy)
ch->op.destroy(ch);
free(ch);
fuse_read_cmd;
fuse_set_getcontext_func;
fuse_setup_compat2;
- fuse_teardown;
};
FUSE_2.4 {
global:
fuse_lowlevel_new_compat;
fuse_main_real_compat22;
- fuse_mount;
fuse_mount_compat22;
fuse_new_compat22;
fuse_opt_parse;
FUSE_2.6 {
global:
fuse_add_direntry;
+ fuse_daemonize;
+ fuse_get_session;
fuse_lowlevel_new;
fuse_lowlevel_new_compat25;
fuse_main_real;
fuse_main_real_compat25;
+ fuse_mount;
+ fuse_mount_compat25;
fuse_new;
fuse_new_compat25;
fuse_opt_insert_arg;
+ fuse_session_remove_chan;
fuse_setup;
fuse_setup_compat25;
+ fuse_teardown;
+ fuse_teardown_compat22;
fuse_unmount;
fuse_unmount_compat22;
fuse_chan_recv;
#include "fuse_i.h"
#include "fuse_opt.h"
#include "fuse_lowlevel.h"
+#include "fuse_common_compat.h"
#include <stdio.h>
#include <stdlib.h>
return -1;
}
-static int fuse_daemonize(int foreground)
+int fuse_daemonize(int foreground)
{
int res;
return 0;
}
+static struct fuse_chan *fuse_mount_common(const char *mountpoint,
+ struct fuse_args *args)
+{
+ struct fuse_chan *ch;
+ int fd = fuse_mount_compat25(mountpoint, args);
+ if (fd == -1)
+ return NULL;
+
+ ch = fuse_kern_chan_new(fd);
+ if (!ch)
+ fuse_unmount(mountpoint, NULL);
+
+ return ch;
+}
+
+struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args)
+{
+ return fuse_mount_common(mountpoint, args);
+}
+
+static void fuse_unmount_common(const char *mountpoint, struct fuse_chan *ch)
+{
+ int fd = ch ? fuse_chan_fd(ch) : -1;
+ fuse_kern_unmount(mountpoint, fd);
+ fuse_chan_destroy(ch);
+}
+
+void fuse_unmount(const char *mountpoint, struct fuse_chan *ch)
+{
+ fuse_unmount_common(mountpoint, ch);
+}
+
static struct fuse *fuse_setup_common(int argc, char *argv[],
const struct fuse_operations *op,
size_t op_size,
char **mountpoint,
int *multithreaded,
int *fd,
+ void *user_data,
int compat)
{
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
+ struct fuse_chan *ch;
struct fuse *fuse;
int foreground;
int res;
if (res == -1)
return NULL;
- *fd = fuse_mount(*mountpoint, &args);
- if (*fd == -1) {
+ ch = fuse_mount_common(*mountpoint, &args);
+ if (!ch) {
fuse_opt_free_args(&args);
goto err_free;
}
- fuse = fuse_new_common(*fd, &args, op, op_size, compat);
+ fuse = fuse_new_common(ch, &args, op, op_size, user_data, compat);
fuse_opt_free_args(&args);
if (fuse == NULL)
goto err_unmount;
if (res == -1)
goto err_destroy;
+ if (fd)
+ *fd = fuse_chan_fd(ch);
+
return fuse;
err_destroy:
fuse_destroy(fuse);
err_unmount:
- fuse_unmount(*mountpoint, *fd);
+ fuse_unmount_common(*mountpoint, ch);
err_free:
free(*mountpoint);
return NULL;
}
struct fuse *fuse_setup(int argc, char *argv[],
- const struct fuse_operations *op,
- size_t op_size, char **mountpoint,
- int *multithreaded, int *fd)
+ const struct fuse_operations *op, size_t op_size,
+ char **mountpoint, int *multithreaded, void *user_data)
{
return fuse_setup_common(argc, argv, op, op_size, mountpoint,
- multithreaded, fd, 0);
+ multithreaded, NULL, user_data, 0);
}
-void fuse_teardown(struct fuse *fuse, int fd, char *mountpoint)
+static void fuse_teardown_common(struct fuse *fuse, char *mountpoint)
{
- fuse_remove_signal_handlers(fuse_get_session(fuse));
- fuse_unmount(mountpoint, fd);
+ struct fuse_session *se = fuse_get_session(fuse);
+ struct fuse_chan *ch = fuse_session_next_chan(se, NULL);
+ fuse_remove_signal_handlers(se);
+ fuse_unmount_common(mountpoint, ch);
fuse_destroy(fuse);
free(mountpoint);
}
+void fuse_teardown(struct fuse *fuse, char *mountpoint)
+{
+ fuse_teardown_common(fuse, mountpoint);
+}
+
static int fuse_main_common(int argc, char *argv[],
const struct fuse_operations *op, size_t op_size,
- int compat)
+ void *user_data, int compat)
{
struct fuse *fuse;
char *mountpoint;
int multithreaded;
int res;
- int fd;
fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint,
- &multithreaded, &fd, compat);
+ &multithreaded, NULL, user_data, compat);
if (fuse == NULL)
return 1;
else
res = fuse_loop(fuse);
- fuse_teardown(fuse, fd, mountpoint);
+ fuse_teardown_common(fuse, mountpoint);
if (res == -1)
return 1;
}
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
- size_t op_size)
+ size_t op_size, void *user_data)
{
- return fuse_main_common(argc, argv, op, op_size, 0);
+ return fuse_main_common(argc, argv, op, op_size, user_data, 0);
}
#undef fuse_main
int *multithreaded, int *fd)
{
return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
- op_size, mountpoint, multithreaded, fd, 22);
+ op_size, mountpoint, multithreaded, fd, NULL, 22);
}
struct fuse *fuse_setup_compat2(int argc, char *argv[],
{
return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
sizeof(struct fuse_operations_compat2),
- mountpoint, multithreaded, fd, 21);
+ mountpoint, multithreaded, fd, NULL, 21);
}
int fuse_main_real_compat22(int argc, char *argv[],
size_t op_size)
{
return fuse_main_common(argc, argv, (struct fuse_operations *) op, op_size,
- 22);
+ NULL, 22);
}
void fuse_main_compat1(int argc, char *argv[],
const struct fuse_operations_compat1 *op)
{
fuse_main_common(argc, argv, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat1), 11);
+ sizeof(struct fuse_operations_compat1), NULL, 11);
}
int fuse_main_compat2(int argc, char *argv[],
const struct fuse_operations_compat2 *op)
{
return fuse_main_common(argc, argv, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat2), 21);
+ sizeof(struct fuse_operations_compat2), NULL, 21);
+}
+
+int fuse_mount_compat1(const char *mountpoint, const char *args[])
+{
+ /* just ignore mount args for now */
+ (void) args;
+ return fuse_mount_compat22(mountpoint, NULL);
}
__asm__(".symver fuse_setup_compat2,__fuse_setup@");
int *multithreaded, int *fd)
{
return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
- op_size, mountpoint, multithreaded, fd, 25);
+ op_size, mountpoint, multithreaded, fd, NULL, 25);
}
int fuse_main_real_compat25(int argc, char *argv[],
size_t op_size)
{
return fuse_main_common(argc, argv, (struct fuse_operations *) op, op_size,
- 25);
+ NULL, 25);
+}
+
+void fuse_teardown_compat22(struct fuse *fuse, int fd, char *mountpoint)
+{
+ (void) fd;
+ fuse_teardown_common(fuse, mountpoint);
+}
+
+int fuse_mount_compat25(const char *mountpoint, struct fuse_args *args)
+{
+ return fuse_kern_mount(mountpoint, args);
}
__asm__(".symver fuse_setup_compat25,fuse_setup@FUSE_2.5");
+__asm__(".symver fuse_teardown_compat22,fuse_teardown@FUSE_2.2");
__asm__(".symver fuse_main_real_compat25,fuse_main_real@FUSE_2.5");
+__asm__(".symver fuse_mount_compat25,fuse_mount@FUSE_2.5");
See the file COPYING.LIB.
*/
-#include "fuse.h"
+#include "fuse_i.h"
#include "fuse_opt.h"
-#include "fuse_compat.h"
#include <stdio.h>
#include <stdlib.h>
return *(int*)CMSG_DATA(cmsg);
}
-void fuse_unmount_compat22(const char *mountpoint)
-{
- fuse_unmount(mountpoint, -1);
-}
-
-void fuse_unmount(const char *mountpoint, int fd)
+void fuse_kern_unmount(const char *mountpoint, int fd)
{
const char *mountprog = FUSERMOUNT_PROG;
- struct pollfd pfd;
- int res;
int pid;
if (!mountpoint)
return;
- pfd.fd = fd;
- pfd.events = 0;
- res = poll(&pfd, 1, 0);
- /* If file poll returns POLLERR on the device file descriptor,
- then the filesystem is already unmounted */
- if (res == 1 && (pfd.revents & POLLERR))
- return;
+ if (fd != -1) {
+ int res;
+ struct pollfd pfd;
+
+ pfd.fd = fd;
+ pfd.events = 0;
+ res = poll(&pfd, 1, 0);
+ /* If file poll returns POLLERR on the device file descriptor,
+ then the filesystem is already unmounted */
+ if (res == 1 && (pfd.revents & POLLERR))
+ return;
+ }
#ifdef HAVE_FORK
pid = fork();
waitpid(pid, NULL, 0);
}
+void fuse_unmount_compat22(const char *mountpoint)
+{
+ fuse_kern_unmount(mountpoint, -1);
+}
+
int fuse_mount_compat22(const char *mountpoint, const char *opts)
{
const char *mountprog = FUSERMOUNT_PROG;
return rv;
}
-int fuse_mount(const char *mountpoint, struct fuse_args *args)
+int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
{
struct mount_opts mo;
int res = -1;
return res;
}
-int fuse_mount_compat1(const char *mountpoint, const char *args[])
-{
- /* just ignore mount args for now */
- (void) args;
- return fuse_mount_compat22(mountpoint, NULL);
-}
-
__asm__(".symver fuse_mount_compat22,fuse_mount@FUSE_2.2");
__asm__(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2");
See the file COPYING.LIB.
*/
-#include "fuse.h"
+#include "fuse_i.h"
#include "fuse_opt.h"
#include <sys/stat.h>
system(umount_cmd);
}
-void fuse_unmount(const char *mountpoint, int fd)
+void fuse_kern_unmount(const char *mountpoint, int fd)
{
char *ep, *umount_cmd, dev[128];
struct stat sbuf;
(void)mountpoint;
-
+
if (fstat(fd, &sbuf) == -1)
return;
devname_r(sbuf.st_rdev, S_IFCHR, dev, 128);
-
+
if (strncmp(dev, "fuse", 4))
return;
-
+
strtol(dev + 4, &ep, 10);
if (*ep != '\0')
return;
return fd;
}
-int fuse_mount(const char *mountpoint, struct fuse_args *args)
+int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
{
struct mount_opts mo;
int res = -1;