From e870a0427adb50a64dc8bcbacfacb089872c6908 Mon Sep 17 00:00:00 2001 From: Nikolaus Rath Date: Fri, 7 Jul 2017 15:25:41 +0200 Subject: [PATCH] Added public fuse_lib_help(), bumped minor version --- ChangeLog.rst | 6 +- configure.ac | 2 +- example/cuse.c | 2 +- example/hello.c | 2 +- example/hello_ll.c | 2 +- example/ioctl.c | 2 +- example/notify_inval_entry.c | 2 +- example/notify_inval_inode.c | 2 +- example/notify_store_retrieve.c | 2 +- example/null.c | 2 +- example/passthrough.c | 2 +- example/passthrough_fh.c | 2 +- example/passthrough_ll.c | 2 +- example/poll.c | 2 +- include/fuse.h | 19 +++++ include/fuse_common.h | 2 +- include/fuse_lowlevel.h | 2 +- lib/Makefile.am | 4 +- lib/fuse.c | 125 ++++++++++++++++++++++---------- lib/fuse_misc.h | 11 +++ lib/fuse_versionscript | 6 ++ lib/helper.c | 12 +-- lib/meson.build | 6 +- meson.build | 2 +- 24 files changed, 151 insertions(+), 70 deletions(-) diff --git a/ChangeLog.rst b/ChangeLog.rst index 864642a..c56c9d2 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,11 +1,15 @@ Unreleased Changes ================== +* Added new `fuse_lib_help()` function. File-systems that previously + passed a ``--help`` option to `fuse_new()` must now process the + ``--help`` option internally and call `fuse_lib_help()` to print the + help for generic FUSE options. * Fixed description of the `fuse_conn_info->time_gran`. The default value of zero actually corresponds to full nanosecond resolution, not one second resolution. * The init script is now installed into the right location - ($DESTDIR/etc/init.d rather than $prefix/$sysconfdir/init.d) + (``$DESTDIR/etc/init.d`` rather than ``$prefix/$sysconfdir/init.d``) * The `example/passthrough_ll` filesystem now supports creating and writing to files. * `fuse_main()` / `fuse_remove_signal_handlers()`: do not reset diff --git a/configure.ac b/configure.ac index fd94a18..894dd85 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(fuse, 3.0.2) +AC_INIT(fuse, 3.1.0) AC_PREREQ(2.59d) AC_CONFIG_MACRO_DIR([m4]) AC_CANONICAL_TARGET diff --git a/example/cuse.c b/example/cuse.c index cfbf753..da17b0d 100644 --- a/example/cuse.c +++ b/example/cuse.c @@ -31,7 +31,7 @@ */ -#define FUSE_USE_VERSION 30 +#define FUSE_USE_VERSION 31 #include diff --git a/example/hello.c b/example/hello.c index 8dec6ad..430a769 100644 --- a/example/hello.c +++ b/example/hello.c @@ -19,7 +19,7 @@ */ -#define FUSE_USE_VERSION 30 +#define FUSE_USE_VERSION 31 #include diff --git a/example/hello_ll.c b/example/hello_ll.c index da3a4fc..74d7191 100644 --- a/example/hello_ll.c +++ b/example/hello_ll.c @@ -18,7 +18,7 @@ * \include hello_ll.c */ -#define FUSE_USE_VERSION 30 +#define FUSE_USE_VERSION 31 #include diff --git a/example/ioctl.c b/example/ioctl.c index 734765d..4053801 100644 --- a/example/ioctl.c +++ b/example/ioctl.c @@ -22,7 +22,7 @@ * \include ioctl.c */ -#define FUSE_USE_VERSION 30 +#define FUSE_USE_VERSION 31 #include diff --git a/example/notify_inval_entry.c b/example/notify_inval_entry.c index 30192d1..b30d073 100644 --- a/example/notify_inval_entry.c +++ b/example/notify_inval_entry.c @@ -73,7 +73,7 @@ */ -#define FUSE_USE_VERSION 30 +#define FUSE_USE_VERSION 31 #include diff --git a/example/notify_inval_inode.c b/example/notify_inval_inode.c index 9bb9316..ebc5a5c 100644 --- a/example/notify_inval_inode.c +++ b/example/notify_inval_inode.c @@ -59,7 +59,7 @@ */ -#define FUSE_USE_VERSION 30 +#define FUSE_USE_VERSION 31 #include diff --git a/example/notify_store_retrieve.c b/example/notify_store_retrieve.c index c7e2957..79617e5 100644 --- a/example/notify_store_retrieve.c +++ b/example/notify_store_retrieve.c @@ -58,7 +58,7 @@ */ -#define FUSE_USE_VERSION 30 +#define FUSE_USE_VERSION 31 #include diff --git a/example/null.c b/example/null.c index bc99a84..3c9033b 100644 --- a/example/null.c +++ b/example/null.c @@ -22,7 +22,7 @@ */ -#define FUSE_USE_VERSION 30 +#define FUSE_USE_VERSION 31 #include diff --git a/example/passthrough.c b/example/passthrough.c index 0c635ca..b83c17f 100644 --- a/example/passthrough.c +++ b/example/passthrough.c @@ -23,7 +23,7 @@ */ -#define FUSE_USE_VERSION 30 +#define FUSE_USE_VERSION 31 #ifdef HAVE_CONFIG_H #include diff --git a/example/passthrough_fh.c b/example/passthrough_fh.c index 372282e..909422a 100644 --- a/example/passthrough_fh.c +++ b/example/passthrough_fh.c @@ -23,7 +23,7 @@ * \include passthrough_fh.c */ -#define FUSE_USE_VERSION 30 +#define FUSE_USE_VERSION 31 #ifdef HAVE_CONFIG_H #include diff --git a/example/passthrough_ll.c b/example/passthrough_ll.c index 84dd847..fc633f5 100644 --- a/example/passthrough_ll.c +++ b/example/passthrough_ll.c @@ -28,7 +28,7 @@ */ #define _GNU_SOURCE -#define FUSE_USE_VERSION 30 +#define FUSE_USE_VERSION 31 #ifdef HAVE_CONFIG_H #include diff --git a/example/poll.c b/example/poll.c index 36a1371..8abca07 100644 --- a/example/poll.c +++ b/example/poll.c @@ -21,7 +21,7 @@ * \include poll.c */ -#define FUSE_USE_VERSION 30 +#define FUSE_USE_VERSION 31 #include diff --git a/include/fuse.h b/include/fuse.h index 0c5741f..f4ac670 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -794,6 +794,19 @@ struct fuse_context { * More detailed API * * ----------------------------------------------------------- */ +/** + * Print available options (high- and low-level) to stdout. This is + * not an exhaustive list, but includes only those options that may be + * of interest to an end-user of a file system. + * + * The function looks at the argument vector only to determine if + * there are additional modules to be loaded (module=foo option), + * and attempts to call their help functions as well. + * + * @param args the argument vector. + */ +void fuse_lib_help(struct fuse_args *args); + /** * Create a new FUSE filesystem. * @@ -821,8 +834,14 @@ struct fuse_context { * `struct fuse_operations.init` handler. * @return the created FUSE handle */ +#if FUSE_USE_VERSION == 30 +#define fuse_new(args, op, size, data) fuse_new_30(args, op, size, data) +#else struct fuse *fuse_new(struct fuse_args *args, const struct fuse_operations *op, size_t op_size, void *private_data); +#endif +struct fuse *fuse_new_30(struct fuse_args *args, const struct fuse_operations *op, + size_t op_size, void *private_data); /** * Mount a FUSE file system. diff --git a/include/fuse_common.h b/include/fuse_common.h index 8bacec5..ecaa906 100644 --- a/include/fuse_common.h +++ b/include/fuse_common.h @@ -22,7 +22,7 @@ #define FUSE_MAJOR_VERSION 3 /** Minor version of FUSE library interface */ -#define FUSE_MINOR_VERSION 0 +#define FUSE_MINOR_VERSION 1 #define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min)) #define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION) diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h index 7a3036d..8e036f5 100644 --- a/include/fuse_lowlevel.h +++ b/include/fuse_lowlevel.h @@ -14,7 +14,7 @@ * Low level API * * IMPORTANT: you should define FUSE_USE_VERSION before including this - * header. To use the newest API define it to 30 (recommended for any + * header. To use the newest API define it to 31 (recommended for any * new application). */ diff --git a/lib/Makefile.am b/lib/Makefile.am index 2ed8b5f..5631f75 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,7 +1,7 @@ ## Process this file with automake to produce Makefile.in AM_CPPFLAGS = -I$(top_srcdir)/include -DFUSERMOUNT_DIR=\"$(bindir)\" \ - -D_REENTRANT -DFUSE_USE_VERSION=30 + -D_REENTRANT -DFUSE_USE_VERSION=31 lib_LTLIBRARIES = libfuse3.la @@ -33,7 +33,7 @@ libfuse3_la_SOURCES = \ $(iconv_source) \ $(mount_source) -libfuse3_la_LDFLAGS = -pthread @libfuse_libs@ -version-number 3:0:2 \ +libfuse3_la_LDFLAGS = -pthread @libfuse_libs@ -version-number 3:1:0 \ -Wl,--version-script,$(srcdir)/fuse_versionscript if NETBSD diff --git a/lib/fuse.c b/lib/fuse.c index d7a7c82..ce29819 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -4400,8 +4400,6 @@ int fuse_interrupted(void) #define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v } static const struct fuse_opt fuse_lib_opts[] = { - FUSE_LIB_OPT("-h", show_help, 1), - FUSE_LIB_OPT("--help", show_help, 1), FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP), FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP), FUSE_LIB_OPT("debug", debug, 1), @@ -4426,7 +4424,34 @@ static const struct fuse_opt fuse_lib_opts[] = { FUSE_OPT_END }; -static void fuse_lib_help(void) +static int fuse_lib_opt_proc(void *data, const char *arg, int key, + struct fuse_args *outargs) +{ + (void) arg; (void) outargs; (void) data; (void) key; + + /* Pass through unknown options */ + return 1; +} + + +static const struct fuse_opt fuse_help_opts[] = { + FUSE_LIB_OPT("modules=%s", modules, 1), + FUSE_OPT_KEY("modules=%s", FUSE_OPT_KEY_KEEP), + FUSE_OPT_END +}; + +static void print_module_help(const char *name, + fuse_module_factory_t *fac) +{ + struct fuse_args a = FUSE_ARGS_INIT(0, NULL); + if (fuse_opt_add_arg(&a, "") == -1 || + fuse_opt_add_arg(&a, "-h") == -1) + return; + printf("\nOptions for %s module:\n", name); + (*fac)(&a, NULL); +} + +void fuse_lib_help(struct fuse_args *args) { /* These are not all options, but only the ones that may be of interest to an end-user */ @@ -4443,37 +4468,42 @@ static void fuse_lib_help(void) " -o noforget never forget cached inodes\n" " -o remember=T remember cached inodes for T seconds (0s)\n" " -o modules=M1[:M2...] names of modules to push onto filesystem stack\n"); -} -static void fuse_lib_help_modules(void) -{ + + /* Print low-level help */ + fuse_lowlevel_help(); + + /* Print help for builtin modules */ + print_module_help("subdir", &fuse_module_subdir_factory); + print_module_help("iconv", &fuse_module_iconv_factory); + + /* Parse command line options in case we need to + activate more modules */ + struct fuse_config conf = { .modules = NULL }; + if (fuse_opt_parse(args, &conf, fuse_help_opts, + fuse_lib_opt_proc) == -1 + || !conf.modules) + return; + + char *module; + char *next; struct fuse_module *m; - printf("\nModule options:\n"); - pthread_mutex_lock(&fuse_context_lock); - for (m = fuse_modules; m; m = m->next) { - struct fuse_fs *fs = NULL; - struct fuse_fs *newfs; - struct fuse_args args = FUSE_ARGS_INIT(0, NULL); - if (fuse_opt_add_arg(&args, "") != -1 && - fuse_opt_add_arg(&args, "-h") != -1) { - printf("\n[%s]\n", m->name); - newfs = m->factory(&args, &fs); - assert(newfs == NULL); - } - fuse_opt_free_args(&args); - } - pthread_mutex_unlock(&fuse_context_lock); -} -static int fuse_lib_opt_proc(void *data, const char *arg, int key, - struct fuse_args *outargs) -{ - (void) arg; (void) outargs; (void) data; (void) key; + // Iterate over all modules + for (module = conf.modules; module; module = next) { + char *p; + for (p = module; *p && *p != ':'; p++); + next = *p ? p + 1 : NULL; + *p = '\0'; - /* Pass through unknown options */ - return 1; + m = fuse_get_module(module); + if (m) + print_module_help(module, &m->factory); + } } + + static int fuse_init_intr_signal(int signum, int *installed) { struct sigaction old_sa; @@ -4595,6 +4625,33 @@ void fuse_stop_cleanup_thread(struct fuse *f) } } + +/* Emulates 3.0-style fuse_new(), which processes + --help */ +FUSE_SYMVER(".symver fuse_new_30,fuse_new@FUSE_3.0"); +FUSE_SYMVER(".symver fuse_new,fuse_new@@FUSE_3.1"); +struct fuse *fuse_new_30(struct fuse_args *args, + const struct fuse_operations *op, + size_t op_size, void *user_data) +{ + struct fuse_config conf; + const struct fuse_opt opts[] = { + FUSE_LIB_OPT("-h", show_help, 1), + FUSE_LIB_OPT("--help", show_help, 1), + FUSE_OPT_END + }; + + if (fuse_opt_parse(args, &conf, opts, + fuse_lib_opt_proc) == -1) + return NULL; + + if (conf.show_help) { + fuse_lib_help(args); + return NULL; + } else + return fuse_new(args, op, op_size, user_data); +} + struct fuse *fuse_new(struct fuse_args *args, const struct fuse_operations *op, size_t op_size, void *user_data) @@ -4620,13 +4677,6 @@ struct fuse *fuse_new(struct fuse_args *args, fuse_lib_opt_proc) == -1) goto out_free; - if (f->conf.show_help) { - fuse_lib_help(); - fuse_lowlevel_help(); - /* Defer printing module help until modules - have been loaded */ - } - pthread_mutex_lock(&fuse_context_lock); static int builtin_modules_registered = 0; /* Have the builtin modules already been registered? */ @@ -4673,11 +4723,6 @@ struct fuse *fuse_new(struct fuse_args *args, } } - if(f->conf.show_help) { - fuse_lib_help_modules(); - goto out_free_fs; - } - if (!f->conf.ac_attr_timeout_set) f->conf.ac_attr_timeout = f->conf.attr_timeout; diff --git a/lib/fuse_misc.h b/lib/fuse_misc.h index 1839a67..2f6663e 100644 --- a/lib/fuse_misc.h +++ b/lib/fuse_misc.h @@ -8,6 +8,17 @@ #include +/* + Versioned symbols cannot be used in some cases because it + - confuse the dynamic linker in uClibc + - not supported on MacOSX (in MachO binary format) +*/ +#if (!defined(__UCLIBC__) && !defined(__APPLE__)) +#define FUSE_SYMVER(x) __asm__(x) +#else +#define FUSE_SYMVER(x) +#endif + #ifndef USE_UCLIBC #define fuse_mutex_init(mut) pthread_mutex_init(mut, NULL) #else diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript index 164e254..5fa3264 100644 --- a/lib/fuse_versionscript +++ b/lib/fuse_versionscript @@ -132,6 +132,12 @@ FUSE_3.0 { *; }; +FUSE_3.1 { + global: + fuse_lib_help; + fuse_new_30; +} FUSE_3.0; + # Local Variables: # indent-tabs-mode: t # End: diff --git a/lib/helper.c b/lib/helper.c index 31640b6..5032b68 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -272,18 +272,15 @@ int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, goto out1; } - /* Re-add --help for later processing by fuse_new() - (that way we also get help for modules options) */ if (opts.show_help) { if(args.argv[0] != '\0') printf("usage: %s [options] \n\n", args.argv[0]); printf("FUSE options:\n"); fuse_cmdline_help(); - if (fuse_opt_add_arg(&args, "--help") == -1) { - res = 1; - goto out1; - } + fuse_lib_help(&args); + res = 0; + goto out1; } if (!opts.show_help && @@ -294,10 +291,9 @@ int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, } - /* --help is processed here and will result in NULL */ fuse = fuse_new(&args, op, op_size, user_data); if (fuse == NULL) { - res = opts.show_help ? 0 : 1; + res = 1; goto out1; } diff --git a/lib/meson.build b/lib/meson.build index 9997187..1cfface 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -25,11 +25,11 @@ if host_machine.system().startswith('netbsd') endif fusermount_path = join_paths(get_option('prefix'), get_option('bindir')) -libfuse = library('fuse3', libfuse_sources, version: '3.0.0', install: true, +libfuse = library('fuse3', libfuse_sources, version: meson.project_version(), soversion: '3', include_directories: include_dirs, - dependencies: deps, + dependencies: deps, install: true, link_depends: 'fuse_versionscript', - c_args: [ '-DFUSE_USE_VERSION=30', + c_args: [ '-DFUSE_USE_VERSION=31', '-DFUSERMOUNT_DIR="{}"'.format(fusermount_path) ], link_args: ['-Wl,--version-script,' + meson.current_source_dir() + '/fuse_versionscript' ]) diff --git a/meson.build b/meson.build index df96f96..7b12631 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('libfuse3', 'c', version: '3.0.2', +project('libfuse3', 'c', version: '3.1.0', meson_version: '>= 0.38', default_options: [ 'buildtype=plain' ]) -- 2.30.2