Added public fuse_lib_help(), bumped minor version
authorNikolaus Rath <Nikolaus@rath.org>
Fri, 7 Jul 2017 13:25:41 +0000 (15:25 +0200)
committerNikolaus Rath <Nikolaus@rath.org>
Sat, 8 Jul 2017 10:48:08 +0000 (12:48 +0200)
24 files changed:
ChangeLog.rst
configure.ac
example/cuse.c
example/hello.c
example/hello_ll.c
example/ioctl.c
example/notify_inval_entry.c
example/notify_inval_inode.c
example/notify_store_retrieve.c
example/null.c
example/passthrough.c
example/passthrough_fh.c
example/passthrough_ll.c
example/poll.c
include/fuse.h
include/fuse_common.h
include/fuse_lowlevel.h
lib/Makefile.am
lib/fuse.c
lib/fuse_misc.h
lib/fuse_versionscript
lib/helper.c
lib/meson.build
meson.build

index 864642a6da45386ac0d5e63d69f7725211d5c507..c56c9d22e369e61e6dfcb70aeb39932580cead07 100644 (file)
@@ -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
index fd94a18467d1b354056feca883908e0f9f92bc44..894dd85a347f0ab6910f8781f79dd1946a01a9fd 100644 (file)
@@ -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
index cfbf7537ef8931288356888f4bbda04b27ebcd54..da17b0df0af83921b94c1496dea79545cba17157 100644 (file)
@@ -31,7 +31,7 @@
  */
 
 
-#define FUSE_USE_VERSION 30
+#define FUSE_USE_VERSION 31
 
 #include <config.h>
 
index 8dec6adef7f91584b012b6a1a288b74ab34fce51..430a7692130c625f5f3c88616e3a625c275fc043 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 
-#define FUSE_USE_VERSION 30
+#define FUSE_USE_VERSION 31
 
 #include <config.h>
 
index da3a4fcb1f6289adeddb35657aabea031a14ce1b..74d7191db936a45fad368a65678d51e4d26a4c11 100644 (file)
@@ -18,7 +18,7 @@
  * \include hello_ll.c
  */
 
-#define FUSE_USE_VERSION 30
+#define FUSE_USE_VERSION 31
 
 #include <config.h>
 
index 734765d93a9e1c9fd9aa1ac696216bc95501703b..40538018489bf99bd5d9f8955a5979a4f2ce0a53 100644 (file)
@@ -22,7 +22,7 @@
  * \include ioctl.c
  */
 
-#define FUSE_USE_VERSION 30
+#define FUSE_USE_VERSION 31
 
 #include <config.h>
 
index 30192d1146117659c5cd8190b2a71cbe05ffeb5d..b30d073021b57601489c05f57531b5c24f29c5f9 100644 (file)
@@ -73,7 +73,7 @@
  */
 
 
-#define FUSE_USE_VERSION 30
+#define FUSE_USE_VERSION 31
 
 #include <config.h>
 
index 9bb9316d77223930022d42d2acb504f140c1fc9f..ebc5a5cd98640c7ca9f7fdf1da8172e5798a53b1 100644 (file)
@@ -59,7 +59,7 @@
  */
 
 
-#define FUSE_USE_VERSION 30
+#define FUSE_USE_VERSION 31
 
 #include <config.h>
 
index c7e29574938494bcdb485bc20bb50ce116056ef1..79617e53a0d0577cfcb3cdfa8f2a72afa7b3f7e9 100644 (file)
@@ -58,7 +58,7 @@
  */
 
 
-#define FUSE_USE_VERSION 30
+#define FUSE_USE_VERSION 31
 
 #include <config.h>
 
index bc99a844c00d764249b74b72c5c127bcfb3e1f95..3c9033bcc4d70dbf0545460303e14a2b89e5b7c4 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 
-#define FUSE_USE_VERSION 30
+#define FUSE_USE_VERSION 31
 
 #include <config.h>
 
index 0c635ca62d2363fda0b9df4a555764ea983c3a03..b83c17f92429a1ddd592755603d8d7baab2297a8 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 
-#define FUSE_USE_VERSION 30
+#define FUSE_USE_VERSION 31
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
index 372282ed66f558cf34ddb2cb3ab55b93ac679312..909422ab9e2cb6fa7ae9a5333210d5decb3d76c7 100644 (file)
@@ -23,7 +23,7 @@
  * \include passthrough_fh.c
  */
 
-#define FUSE_USE_VERSION 30
+#define FUSE_USE_VERSION 31
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
index 84dd847f75cd86cd46bc63f5f85efc58509a00ee..fc633f534d6cfe5a5978d274098ae80f9cb74788 100644 (file)
@@ -28,7 +28,7 @@
  */
 
 #define _GNU_SOURCE
-#define FUSE_USE_VERSION 30
+#define FUSE_USE_VERSION 31
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
index 36a1371184decf04eed6b30cc4c92bcc3a55969d..8abca0784af4c41e9f54acac5298d4fca6fec149 100644 (file)
@@ -21,7 +21,7 @@
  * \include poll.c
  */
 
-#define FUSE_USE_VERSION 30
+#define FUSE_USE_VERSION 31
 
 #include <config.h>
 
index 0c5741fc9038b489516452b1af7e684b95a92954..f4ac670f8c78ea2f3a6040ef011c63f92290225d 100644 (file)
@@ -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.
index 8bacec5bb506bcb6f564431c55c4792c21b18fc3..ecaa9061d4f6cabce49fc348a8e5c1132d9a1960 100644 (file)
@@ -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)
index 7a3036db987a5c3d1851b17b3861246cfe8f890f..8e036f5b8e029a4b3f4a74747b18d2730d96dccc 100644 (file)
@@ -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).
  */
 
index 2ed8b5f5a337e71b8fb73905c1ac2b31ce14542c..5631f759be16afb6ca001bb27528fd311738607e 100644 (file)
@@ -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
index d7a7c82b5fbd803d802b1fc70a0e391857ce281f..ce298192e99aba41d03416e16ff6aa4c00994128 100644 (file)
@@ -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;
 
index 1839a67041b94e11e143fe68c18ada92e42bb1a4..2f6663ed7d8f3b5d2ba20d48003a96734608dd62 100644 (file)
@@ -8,6 +8,17 @@
 
 #include <pthread.h>
 
+/*
+  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
index 164e25482f259a874bc2b8921bf798a3ff3bf4e3..5fa3264f0fa0434b62297978d3a2d96d3ffae4c9 100644 (file)
@@ -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:
index 31640b6e6937c8bf685847ed817ad9d358f97282..5032b6809b062beff13b728ff9a7b909c2bf52e2 100644 (file)
@@ -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] <mountpoint>\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;
        }
 
index 999718757317856a0e7a7d319479acfdb5a664ac..1cfface68eea775202a99d2afe6dae137d1c44a3 100644 (file)
@@ -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' ])
index df96f96a86b2b04fc834eb9165a2f2356610ef88..7b126314b19ad6eb28bf00e6568b51f94d2fd5ef 100644 (file)
@@ -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' ])