Avoid nested function declarations in helper functions
authorBernd Schubert <bschubert@ddn.com>
Mon, 17 Feb 2025 22:39:04 +0000 (23:39 +0100)
committerBernd Schubert <bernd@bsbernd.com>
Tue, 18 Feb 2025 21:32:49 +0000 (22:32 +0100)
libfuse-3.17 introduced several functions that should only be called via
inlined helper functions, never directly. To enforce this, these functions
were declared within the inlined functions. However, this triggers the
compiler warning "-Werror=nested-externs".

While this warning is valid, the nested declarations were intentional to
prevent direct usage of these functions. Rather than suppressing the
warning with pragmas, move these function declarations outside the helper
functions while maintaining the intended access restrictions through other
means.

Closes: https://github.com/libfuse/libfuse/issues/1134
Signed-off-by: Bernd Schubert <bschubert@ddn.com>
include/fuse.h
include/fuse_lowlevel.h
lib/fuse.c
lib/fuse_lowlevel.c
lib/helper.c

index c0857fdbe8eaff559b5d22fdfc29d1a49e6c4fdf..c94b628514a6057449c62f861208eea08858d17d 100644 (file)
@@ -882,6 +882,9 @@ struct fuse_context {
  *
  * Do not call this directly, use fuse_main()
  */
+int fuse_main_real_versioned(int argc, char *argv[],
+                            const struct fuse_operations *op, size_t op_size,
+                            struct libfuse_version *version, void *user_data);
 static inline int fuse_main_real(int argc, char *argv[],
                                 const struct fuse_operations *op,
                                 size_t op_size, void *user_data)
@@ -895,13 +898,6 @@ static inline int fuse_main_real(int argc, char *argv[],
                 "%s is a libfuse internal function, please use fuse_main()\n",
                 __func__);
 
-       /* not declared globally, to restrict usage of this function */
-       int fuse_main_real_versioned(int argc, char *argv[],
-                                    const struct fuse_operations *op,
-                                    size_t op_size,
-                                    struct libfuse_version *version,
-                                    void *user_data);
-
        return fuse_main_real_versioned(argc, argv, op, op_size, &version,
                                        user_data);
 }
@@ -960,6 +956,9 @@ static inline int fuse_main_real(int argc, char *argv[],
  *
  * Example usage, see hello.c
  */
+int fuse_main_real_versioned(int argc, char *argv[],
+                            const struct fuse_operations *op, size_t op_size,
+                            struct libfuse_version *version, void *user_data);
 static inline int fuse_main_fn(int argc, char *argv[],
                               const struct fuse_operations *op,
                               void *user_data)
@@ -971,12 +970,6 @@ static inline int fuse_main_fn(int argc, char *argv[],
                .padding = 0
        };
 
-       /* not declared globally, to restrict usage of this function */
-       int fuse_main_real_versioned(int argc, char *argv[],
-                                    const struct fuse_operations *op,
-                                    size_t op_size,
-                                    struct libfuse_version *version,
-                                    void *user_data);
        return fuse_main_real_versioned(argc, argv, op, sizeof(*(op)), &version,
                                        user_data);
 }
@@ -1000,6 +993,14 @@ static inline int fuse_main_fn(int argc, char *argv[],
  */
 void fuse_lib_help(struct fuse_args *args);
 
+/* Do not call this directly, use fuse_new() instead */
+struct fuse *_fuse_new_30(struct fuse_args *args,
+                         const struct fuse_operations *op, size_t op_size,
+                         struct libfuse_version *version, void *user_data);
+struct fuse *_fuse_new_31(struct fuse_args *args,
+                         const struct fuse_operations *op, size_t op_size,
+                         struct libfuse_version *version, void *user_data);
+
 /**
  * Create a new FUSE filesystem.
  *
@@ -1028,22 +1029,10 @@ void fuse_lib_help(struct fuse_args *args);
  * @return the created FUSE handle
  */
 #if FUSE_USE_VERSION == 30
-struct fuse *_fuse_new_30(struct fuse_args *args,
-                        const struct fuse_operations *op,
-                        size_t op_size,
-                        struct libfuse_version *version,
-                        void *user_data);
-static inline struct fuse *
-fuse_new_fn(struct fuse_args *args,
-        const struct fuse_operations *op, size_t op_size,
-        void *user_data)
+static inline struct fuse *fuse_new_fn(struct fuse_args *args,
+                                      const struct fuse_operations *op,
+                                      size_t op_size, void *user_data)
 {
-       /* not declared globally, to restrict usage of this function */
-       struct fuse *_fuse_new_30(struct fuse_args *args,
-                              const struct fuse_operations *op, size_t op_size,
-                              struct libfuse_version *version,
-                              void *user_data);
-
        struct libfuse_version version = {
                .major = FUSE_MAJOR_VERSION,
                .minor = FUSE_MINOR_VERSION,
@@ -1054,10 +1043,9 @@ fuse_new_fn(struct fuse_args *args,
        return _fuse_new_30(args, op, op_size, &version, user_data);
 }
 #else /* FUSE_USE_VERSION */
-static inline struct fuse *
-fuse_new_fn(struct fuse_args *args,
-        const struct fuse_operations *op, size_t op_size,
-        void *user_data)
+static inline struct fuse *fuse_new_fn(struct fuse_args *args,
+                                      const struct fuse_operations *op,
+                                      size_t op_size, void *user_data)
 {
        struct libfuse_version version = {
                .major = FUSE_MAJOR_VERSION,
@@ -1066,11 +1054,6 @@ fuse_new_fn(struct fuse_args *args,
                .padding = 0
        };
 
-       /* not declared globally, to restrict usage of this function */
-       struct fuse *_fuse_new_31(struct fuse_args *args,
-               const struct fuse_operations *op,
-               size_t op_size, struct libfuse_version *version,
-               void *user_data);
        return _fuse_new_31(args, op, op_size, &version, user_data);
 }
 #endif
index b03b37aaeabe0be566531a170e0c50388692c399..93bcba296c2d3f8484c8314e1fcdbf34f3439524 100644 (file)
@@ -2049,6 +2049,12 @@ int fuse_parse_cmdline_312(struct fuse_args *args,
 #endif
 #endif
 
+/* Do not call this directly, use fuse_session_new() instead */
+struct fuse_session *
+fuse_session_new_versioned(struct fuse_args *args,
+                          const struct fuse_lowlevel_ops *op, size_t op_size,
+                          struct libfuse_version *version, void *userdata);
+
 /**
  * Create a low level session.
  *
@@ -2088,12 +2094,6 @@ fuse_session_new_fn(struct fuse_args *args, const struct fuse_lowlevel_ops *op,
                .padding = 0
        };
 
-       /* not declared globally, to restrict usage of this function */
-       struct fuse_session *fuse_session_new_versioned(
-               struct fuse_args *args, const struct fuse_lowlevel_ops *op,
-               size_t op_size, struct libfuse_version *version,
-               void *userdata);
-
        return fuse_session_new_versioned(args, op, op_size, &version,
                                          userdata);
 }
index 6c69a6897fa50c21d8300c9666a2290a144604db..933542992fc4c9d2d0d4ba1d949d2f76bc2e8da9 100644 (file)
@@ -4924,13 +4924,8 @@ void fuse_stop_cleanup_thread(struct fuse *f)
  * through the fuse_new macro
  */
 struct fuse *_fuse_new_31(struct fuse_args *args,
-                          const struct fuse_operations *op,
-                          size_t op_size, struct libfuse_version *version,
-                          void *user_data);
-struct fuse *_fuse_new_31(struct fuse_args *args,
-                          const struct fuse_operations *op,
-                          size_t op_size, struct libfuse_version *version,
-                          void *user_data)
+                         const struct fuse_operations *op, size_t op_size,
+                         struct libfuse_version *version, void *user_data)
 {
        struct fuse *f;
        struct node *root;
@@ -5075,10 +5070,6 @@ out:
 }
 
 /* Emulates 3.0-style fuse_new(), which processes --help */
-struct fuse *_fuse_new_30(struct fuse_args *args, const struct fuse_operations *op,
-                        size_t op_size,
-                        struct libfuse_version *version,
-                        void *user_data);
 FUSE_SYMVER("_fuse_new_30", "_fuse_new@FUSE_3.0")
 struct fuse *_fuse_new_30(struct fuse_args *args,
                         const struct fuse_operations *op,
index e3e79d5284e34e717fd939821fe35e455ab8f0b9..d650944a3e944a665a8643a88fb39b12851617ea 100644 (file)
@@ -3244,10 +3244,6 @@ int fuse_session_receive_buf_internal(struct fuse_session *se,
        return _fuse_session_receive_buf(se, buf, ch, true);
 }
 
-struct fuse_session *
-fuse_session_new_versioned(struct fuse_args *args,
-                          const struct fuse_lowlevel_ops *op, size_t op_size,
-                          struct libfuse_version *version, void *userdata);
 struct fuse_session *
 fuse_session_new_versioned(struct fuse_args *args,
                           const struct fuse_lowlevel_ops *op, size_t op_size,
index a1cf98c3ec2b0a8edcb4f52c0163c4e52eb8c053..a7b2fe0029b1b659394ef56c050936a54f948292 100644 (file)
@@ -304,10 +304,6 @@ int fuse_daemonize(int foreground)
        return 0;
 }
 
-/* Not symboled, as not part of the official API */
-int fuse_main_real_versioned(int argc, char *argv[],
-                            const struct fuse_operations *op, size_t op_size,
-                            struct libfuse_version *version, void *user_data);
 int fuse_main_real_versioned(int argc, char *argv[],
                             const struct fuse_operations *op, size_t op_size,
                             struct libfuse_version *version, void *user_data)