cleanups + step minor version
authorMiklos Szeredi <miklos@szeredi.hu>
Thu, 21 Oct 2004 09:35:10 +0000 (09:35 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Thu, 21 Oct 2004 09:35:10 +0000 (09:35 +0000)
ChangeLog
example/fusexmp.c
example/hello.c
example/null.c
include/fuse.h
lib/Makefile.am
lib/helper.c

index efef652290e6131d27c11ae119d01f2f52d72abf..98d41c99ae02509d6698cac0021b6f2eef17f6a6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2004-10-21  Miklos Szeredi <miklos@szeredi.hu>
+
+       * 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 <miklos@szeredi.hu>
 
        * Released 1.9
index a905b584ca6dd7630fae9b2e7b6cde8fe9037254..9b86a4c3f0900ceb10889a0aa37881e209c06976 100644 (file)
@@ -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);
 }
index 040c835ced3abda1d1f947b3134c36f881c2f1f2..c7a0c1c4f625b32c82fcff37f45b5e982db1d21f 100644 (file)
@@ -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);
 }
index 2eb5c8e3c45d1900c9dabef85b6e13310542d3fc..b854289479544f5dba8e43d4b8f432a29e315cf3 100644 (file)
@@ -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);
 }
index 3c68a8e2ae74b7eec3e628e9bfc50b3111f38e1d..705c4fdb6de6e7c647aa20e41834b332196132c5 100644 (file)
@@ -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);
index 64385be4c3ef779bd82c82f3f26fceea232b8185..8dcd5a8ff20945c7161a6dea42cf8659abe032ea 100644 (file)
@@ -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
index 6031c5f6d4ceddb54b8fa21d6cfebf7993e43767..ff4feea05d6a7d6d4d68b3d5a5cd36f61e92afad 100644 (file)
@@ -15,9 +15,9 @@
 #include <limits.h>
 #include <signal.h>
 
-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;
 }