From: Miklos Szeredi Date: Thu, 21 Oct 2004 09:35:10 +0000 (+0000) Subject: cleanups + step minor version X-Git-Tag: fuse_2_0_pre0~9 X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=5dc8a80c655cea3717996c8f419fc73be133b647;p=qemu-gpiodev%2Flibfuse.git cleanups + step minor version --- diff --git a/ChangeLog b/ChangeLog index efef652..98d41c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2004-10-21 Miklos Szeredi + + * fuse_main() now does not exit on erro, rather it returns an + error code + + * exported __fuse_setup() and __fuse_teardown() functions, which + make it easier to implement a custom event loop. + 2004-10-14 Miklos Szeredi * Released 1.9 diff --git a/example/fusexmp.c b/example/fusexmp.c index a905b58..9b86a4c 100644 --- a/example/fusexmp.c +++ b/example/fusexmp.c @@ -337,6 +337,5 @@ static struct fuse_operations xmp_oper = { int main(int argc, char *argv[]) { - fuse_main(argc, argv, &xmp_oper); - return 0; + return fuse_main(argc, argv, &xmp_oper); } diff --git a/example/hello.c b/example/hello.c index 040c835..c7a0c1c 100644 --- a/example/hello.c +++ b/example/hello.c @@ -84,6 +84,5 @@ static struct fuse_operations hello_oper = { int main(int argc, char *argv[]) { - fuse_main(argc, argv, &hello_oper); - return 0; + return fuse_main(argc, argv, &hello_oper); } diff --git a/example/null.c b/example/null.c index 2eb5c8e..b854289 100644 --- a/example/null.c +++ b/example/null.c @@ -74,6 +74,5 @@ static struct fuse_operations null_oper = { int main(int argc, char *argv[]) { - fuse_main(argc, argv, &null_oper); - return 0; + return fuse_main(argc, argv, &null_oper); } diff --git a/include/fuse.h b/include/fuse.h index 3c68a8e..705c4fd 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -15,7 +15,7 @@ #define FUSE_MAJOR_VERSION 2 /** Minor version of FUSE library interface */ -#define FUSE_MINOR_VERSION 0 +#define FUSE_MINOR_VERSION 1 /* This interface uses 64 bit off_t */ #if _FILE_OFFSET_BITS != 64 @@ -161,18 +161,9 @@ extern "C" { * @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 + * @return 0 on success, nonzero on failure */ -void fuse_main(int argc, char *argv[], const struct fuse_operations *op); - -/** - * Invalidate cached data of a file. - * - * Useful if the 'kernel_cache' mount option is given, since in that - * case the cache is not invalidated on file open. - * - * @return 0 on success or -errno on failure - */ -int fuse_invalidate(struct fuse *f, const char *path); +int fuse_main(int argc, char *argv[], const struct fuse_operations *op); /* ----------------------------------------------------------- * * More detailed API * @@ -261,6 +252,16 @@ int fuse_loop_mt(struct fuse *f); */ struct fuse_context *fuse_get_context(void); +/** + * Invalidate cached data of a file. + * + * Useful if the 'kernel_cache' mount option is given, since in that + * case the cache is not invalidated on file open. + * + * @return 0 on success or -errno on failure + */ +int fuse_invalidate(struct fuse *f, const char *path); + /** * Check whether a mount option should be passed to the kernel or the * library @@ -277,6 +278,10 @@ int fuse_is_lib_option(const char *opt); struct fuse_cmd; typedef void (*fuse_processor_t)(struct fuse *, struct fuse_cmd *, void *); +struct fuse *__fuse_setup(int argc, char *argv[], + const struct fuse_operations *op, + char **mountpoint, int *multithreaded, int *fd); +void __fuse_teardown(struct fuse *fuse, int fd, char *mountpoint); struct fuse_cmd *__fuse_read_cmd(struct fuse *f); void __fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd); int __fuse_loop_mt(struct fuse *f, fuse_processor_t proc, void *data); diff --git a/lib/Makefile.am b/lib/Makefile.am index 64385be..8dcd5a8 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -9,4 +9,4 @@ libfuse_la_SOURCES = \ mount.c \ fuse_i.h -libfuse_la_LDFLAGS = -lpthread -version-number 2:0:0 +libfuse_la_LDFLAGS = -lpthread -version-number 2:1:0 diff --git a/lib/helper.c b/lib/helper.c index 6031c5f..ff4feea 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -15,9 +15,9 @@ #include #include -static struct fuse *fuse; +static struct fuse *fuse_obj; -static void usage(char *progname) +static void usage(const char *progname) { fprintf(stderr, "usage: %s mountpoint [options]\n" @@ -39,22 +39,21 @@ static void usage(char *progname) " debug enable debug output\n" " fsname=NAME set filesystem name in mtab\n", progname); - exit(1); } -static void invalid_option(char *argv[], int argctr) +static void invalid_option(const char *argv[], int argctr) { - fprintf(stderr, "invalid option: %s\n\n", argv[argctr]); + fprintf(stderr, "fuse: invalid option: %s\n\n", argv[argctr]); usage(argv[0]); } static void exit_handler() { - if (fuse != NULL) - fuse_exit(fuse); + if (fuse_obj != NULL) + fuse_exit(fuse_obj); } -static void set_one_signal_handler(int signal, void (*handler)(int)) +static int set_one_signal_handler(int signal, void (*handler)(int)) { struct sigaction sa; struct sigaction old_sa; @@ -66,54 +65,24 @@ static void set_one_signal_handler(int signal, void (*handler)(int)) if (sigaction(signal, NULL, &old_sa) == -1) { perror("FUSE: cannot get old signal handler"); - exit(1); + return -1; } if (old_sa.sa_handler == SIG_DFL && sigaction(signal, &sa, NULL) == -1) { perror("Cannot set signal handler"); - exit(1); + return -1; } + return 0; } -static void set_signal_handlers() -{ - set_one_signal_handler(SIGHUP, exit_handler); - set_one_signal_handler(SIGINT, exit_handler); - set_one_signal_handler(SIGTERM, exit_handler); - set_one_signal_handler(SIGPIPE, SIG_IGN); -} - -static int fuse_do(int fuse_fd, const char *opts, int multithreaded, - int background, const struct fuse_operations *op) +static int set_signal_handlers() { - int pid; - int res; - - fuse = fuse_new(fuse_fd, opts, op); - if (fuse == NULL) - return 1; - - if (background) { - pid = fork(); - if (pid == -1) - return 1; - - if (pid) - exit(0); - } - - set_signal_handlers(); - - if (multithreaded) - res = fuse_loop_mt(fuse); - else - res = fuse_loop(fuse); - - fuse_destroy(fuse); - - if (res == -1) - return 1; + if (set_one_signal_handler(SIGHUP, exit_handler) == -1 || + set_one_signal_handler(SIGINT, exit_handler) == -1 || + set_one_signal_handler(SIGTERM, exit_handler) == -1 || + set_one_signal_handler(SIGPIPE, SIG_IGN) == -1) + return -1; return 0; } @@ -137,7 +106,7 @@ static int add_option_to(const char *opt, char **optp) return 0; } -static void add_options(char **lib_optp, char **kernel_optp, const char *opts) +static int add_options(char **lib_optp, char **kernel_optp, const char *opts) { char *xopts = strdup(opts); char *s = xopts; @@ -145,7 +114,7 @@ static void add_options(char **lib_optp, char **kernel_optp, const char *opts) if (xopts == NULL) { fprintf(stderr, "fuse: memory allocation failed\n"); - exit(1); + return -1; } while((opt = strsep(&s, ",")) != NULL) { @@ -156,24 +125,27 @@ static void add_options(char **lib_optp, char **kernel_optp, const char *opts) res = add_option_to(opt, kernel_optp); if (res == -1) { fprintf(stderr, "fuse: memory allocation failed\n"); - exit(1); + return -1; } } free(xopts); + return 0; } -void fuse_main(int argc, char *argv[], const struct fuse_operations *op) +static int fuse_parse_cmdline(int argc, const char *argv[], char **kernel_opts, + char **lib_opts, char **mountpoint, + int *multithreaded, int *background) { + int res; int argctr; - int multithreaded; - int background; - int fuse_fd; - char *fuse_mountpoint = NULL; - char *basename; - char *kernel_opts = NULL; - char *lib_opts = NULL; + const char *basename; char *fsname_opt; - int err; + + *kernel_opts = NULL; + *lib_opts = NULL; + *mountpoint = NULL; + *multithreaded = 1; + *background = 1; basename = strrchr(argv[0], '/'); if (basename == NULL) @@ -184,14 +156,14 @@ void fuse_main(int argc, char *argv[], const struct fuse_operations *op) fsname_opt = malloc(strlen(basename) + 64); if (fsname_opt == NULL) { fprintf(stderr, "fuse: memory allocation failed\n"); - exit(1); + return -1; } sprintf(fsname_opt, "fsname=%s", basename); - add_options(&lib_opts, &kernel_opts, fsname_opt); + res = add_options(lib_opts, kernel_opts, fsname_opt); free(fsname_opt); + if (res == -1) + goto err; - multithreaded = 1; - background = 1; for (argctr = 1; argctr < argc; argctr ++) { if (argv[argctr][0] == '-') { if (strlen(argv[argctr]) == 2) @@ -200,65 +172,155 @@ void fuse_main(int argc, char *argv[], const struct fuse_operations *op) if (argctr + 1 == argc || argv[argctr+1][0] == '-') { fprintf(stderr, "missing option after -o\n\n"); usage(argv[0]); + goto err; } argctr ++; - add_options(&lib_opts, &kernel_opts, argv[argctr]); + res = add_options(lib_opts, kernel_opts, argv[argctr]); + if (res == -1) + goto err; break; case 'd': - add_options(&lib_opts, &kernel_opts, "debug"); - background = 0; + res = add_options(lib_opts, kernel_opts, "debug"); + if (res == -1) + goto err; + *background = 0; break; case 'f': - background = 0; + *background = 0; break; case 's': - multithreaded = 0; + *multithreaded = 0; break; case 'h': usage(argv[0]); - break; + goto err; default: invalid_option(argv, argctr); + goto err; } else { - if (argv[argctr][1] == 'o') - add_options(&lib_opts, &kernel_opts, &argv[argctr][2]); - else + if (argv[argctr][1] == 'o') { + res = add_options(lib_opts, kernel_opts, &argv[argctr][2]); + if (res == -1) + goto err; + } + else { invalid_option(argv, argctr); + goto err; + } } - } else if (fuse_mountpoint == NULL) { - fuse_mountpoint = strdup(argv[argctr]); - if (fuse_mountpoint == NULL) { + } else if (*mountpoint == NULL) { + *mountpoint = strdup(argv[argctr]); + if (*mountpoint == NULL) { fprintf(stderr, "fuse: memory allocation failed\n"); - exit(1); + goto err; } } - else + else { invalid_option(argv, argctr); + goto err; + } } - if (fuse_mountpoint == NULL) { + if (*mountpoint == NULL) { fprintf(stderr, "missing mountpoint\n\n"); usage(argv[0]); + goto err; } + return 0; + + err: + free(*kernel_opts); + free(*lib_opts); + free(*mountpoint); + return -1; +} + + +struct fuse *__fuse_setup(int argc, char *argv[], + const struct fuse_operations *op, + char **mountpoint, int *multithreaded, int *fd) +{ + struct fuse *fuse; + int background; + char *kernel_opts; + char *lib_opts; + int res; + + res = fuse_parse_cmdline(argc, (const char **) argv, &kernel_opts, + &lib_opts, mountpoint, multithreaded, + &background); + if (res == -1) + return NULL; + + *fd = fuse_mount(*mountpoint, kernel_opts); + if (*fd == -1) + goto err_free; + + fuse = fuse_new(*fd, lib_opts, op); + if (fuse == NULL) + goto err_unmount; + + if (background) { + res = daemon(0, 0); + if (res == -1) { + perror("fuse: failed to daemonize program\n"); + goto err_destroy; + } + } + res = set_signal_handlers(); + if (res == -1) + goto err_destroy; + + free(kernel_opts); + free(lib_opts); + return fuse; + + err_destroy: + fuse_destroy(fuse); + err_unmount: + fuse_unmount(*mountpoint); + err_free: + free(kernel_opts); + free(lib_opts); + free(*mountpoint); + return NULL; +} + +void __fuse_teardown(struct fuse *fuse, int fd, char *mountpoint) +{ + fuse_destroy(fuse); + close(fd); + fuse_unmount(mountpoint); + free(mountpoint); +} + + +int fuse_main(int argc, char *argv[], const struct fuse_operations *op) +{ + char *mountpoint; + int multithreaded; + int res; + int fd; + + fuse_obj = __fuse_setup(argc, argv, op, &mountpoint, &multithreaded, &fd); + if (fuse_obj == NULL) + return 1; + + if (multithreaded) + res = fuse_loop_mt(fuse_obj); + else + res = fuse_loop(fuse_obj); - fuse_fd = fuse_mount(fuse_mountpoint, kernel_opts); - if (fuse_fd == -1) - exit(1); - if (kernel_opts) - free(kernel_opts); - - err = fuse_do(fuse_fd, lib_opts, multithreaded, background, op); - if (lib_opts) - free(lib_opts); - close(fuse_fd); - fuse_unmount(fuse_mountpoint); - if (err) - exit(err); + __fuse_teardown(fuse_obj, fd, mountpoint); + if (res == -1) + return 1; + + return 0; }