⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 helper.c

📁 Linux下fuse用户文件系统的的源代码
💻 C
字号:
/*    FUSE: Filesystem in Userspace    Copyright (C) 2001-2006  Miklos Szeredi <miklos@szeredi.hu>    This program can be distributed under the terms of the GNU LGPL.    See the file COPYING.LIB.*/#include "config.h"#include "fuse_i.h"#include "fuse_opt.h"#include "fuse_lowlevel.h"#include "fuse_common_compat.h"#include <stdio.h>#include <stdlib.h>#include <stddef.h>#include <unistd.h>#include <string.h>#include <limits.h>#include <errno.h>enum  {    KEY_HELP,    KEY_HELP_NOHEADER,    KEY_VERSION,};struct helper_opts {    int singlethread;    int foreground;    int fsname;    char *mountpoint;};#define FUSE_HELPER_OPT(t, p) { t, offsetof(struct helper_opts, p), 1 }static const struct fuse_opt fuse_helper_opts[] = {    FUSE_HELPER_OPT("-d",          foreground),    FUSE_HELPER_OPT("debug",       foreground),    FUSE_HELPER_OPT("-f",          foreground),    FUSE_HELPER_OPT("-s",          singlethread),    FUSE_HELPER_OPT("fsname=",     fsname),    FUSE_OPT_KEY("-h",          KEY_HELP),    FUSE_OPT_KEY("--help",      KEY_HELP),    FUSE_OPT_KEY("-ho",         KEY_HELP_NOHEADER),    FUSE_OPT_KEY("-V",          KEY_VERSION),    FUSE_OPT_KEY("--version",   KEY_VERSION),    FUSE_OPT_KEY("-d",          FUSE_OPT_KEY_KEEP),    FUSE_OPT_KEY("debug",       FUSE_OPT_KEY_KEEP),    FUSE_OPT_KEY("fsname=",     FUSE_OPT_KEY_KEEP),    FUSE_OPT_END};static void usage(const char *progname){    fprintf(stderr,            "usage: %s mountpoint [options]\n\n", progname);    fprintf(stderr,            "general options:\n"            "    -o opt,[opt...]        mount options\n"            "    -h   --help            print help\n"            "    -V   --version         print version\n"            "\n");}static void helper_help(void){    fprintf(stderr,            "FUSE options:\n"            "    -d   -o debug          enable debug output (implies -f)\n"            "    -f                     foreground operation\n"            "    -s                     disable multi-threaded operation\n"            "\n"            );}static void helper_version(void){    fprintf(stderr, "FUSE library version: %s\n", PACKAGE_VERSION);}static int fuse_helper_opt_proc(void *data, const char *arg, int key,                                struct fuse_args *outargs){    struct helper_opts *hopts = data;    switch (key) {    case KEY_HELP:        usage(outargs->argv[0]);        /* fall through */    case KEY_HELP_NOHEADER:        helper_help();        return fuse_opt_add_arg(outargs, "-h");    case KEY_VERSION:        helper_version();        return 1;    case FUSE_OPT_KEY_NONOPT:        if (!hopts->mountpoint) {            char mountpoint[PATH_MAX];            if (realpath(arg, mountpoint) == NULL) {                fprintf(stderr, "fuse: bad mount point `%s': %s\n", arg, strerror(errno));                return -1;            }            return fuse_opt_add_opt(&hopts->mountpoint, mountpoint);        } else {            fprintf(stderr, "fuse: invalid argument `%s'\n", arg);            return -1;        }    default:        return 1;    }}static int add_default_fsname(const char *progname, struct fuse_args *args){    int res;    char *fsname_opt;    const char *basename = strrchr(progname, '/');    if (basename == NULL)        basename = progname;    else if (basename[1] != '\0')        basename++;    fsname_opt = (char *) malloc(strlen(basename) + 64);    if (fsname_opt == NULL) {        fprintf(stderr, "fuse: memory allocation failed\n");        return -1;    }    sprintf(fsname_opt, "-ofsname=%s", basename);    res = fuse_opt_add_arg(args, fsname_opt);    free(fsname_opt);    return res;}int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint,                       int *multithreaded, int *foreground){    int res;    struct helper_opts hopts;    memset(&hopts, 0, sizeof(hopts));    res = fuse_opt_parse(args, &hopts, fuse_helper_opts, fuse_helper_opt_proc);    if (res == -1)        return -1;    if (!hopts.fsname) {        res = add_default_fsname(args->argv[0], args);        if (res == -1)            goto err;    }    if (mountpoint)        *mountpoint = hopts.mountpoint;    else        free(hopts.mountpoint);    if (multithreaded)        *multithreaded = !hopts.singlethread;    if (foreground)        *foreground = hopts.foreground;    return 0; err:    free(hopts.mountpoint);    return -1;}int fuse_daemonize(int foreground){    int res;    if (!foreground) {        res = daemon(0, 0);        if (res == -1) {            perror("fuse: failed to daemonize program\n");            return -1;        }    } else {        /* Ensure consistant behavior across debug and normal modes */        res = chdir("/");        if (res == -1) {            perror("fuse: failed to change working directory to /\n");            return -1;        }    }    return 0;}static struct fuse_chan *fuse_mount_common(const char *mountpoint,                                           struct fuse_args *args){    struct fuse_chan *ch;    int fd = fuse_mount_compat25(mountpoint, args);    if (fd == -1)        return NULL;    ch = fuse_kern_chan_new(fd);    if (!ch)        fuse_kern_unmount(mountpoint, fd);    return ch;}struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args){    return fuse_mount_common(mountpoint, args);}static void fuse_unmount_common(const char *mountpoint, struct fuse_chan *ch){    int fd = ch ? fuse_chan_fd(ch) : -1;    fuse_kern_unmount(mountpoint, fd);    fuse_chan_destroy(ch);}void fuse_unmount(const char *mountpoint, struct fuse_chan *ch){    fuse_unmount_common(mountpoint, ch);}static struct fuse *fuse_setup_common(int argc, char *argv[],                                      const struct fuse_operations *op,                                      size_t op_size,                                      char **mountpoint,                                      int *multithreaded,                                      int *fd,                                      void *user_data,                                      int compat){    struct fuse_args args = FUSE_ARGS_INIT(argc, argv);    struct fuse_chan *ch;    struct fuse *fuse;    int foreground;    int res;    res = fuse_parse_cmdline(&args, mountpoint, multithreaded, &foreground);    if (res == -1)        return NULL;    ch = fuse_mount_common(*mountpoint, &args);    if (!ch) {        fuse_opt_free_args(&args);        goto err_free;    }    fuse = fuse_new_common(ch, &args, op, op_size, user_data, compat);    fuse_opt_free_args(&args);    if (fuse == NULL)        goto err_unmount;    res = fuse_daemonize(foreground);    if (res == -1)        goto err_unmount;    res = fuse_set_signal_handlers(fuse_get_session(fuse));    if (res == -1)        goto err_unmount;    if (fd)        *fd = fuse_chan_fd(ch);    return fuse; err_unmount:    fuse_unmount_common(*mountpoint, ch);    if (fuse)        fuse_destroy(fuse); err_free:    free(*mountpoint);    return NULL;}struct fuse *fuse_setup(int argc, char *argv[],                        const struct fuse_operations *op, size_t op_size,                        char **mountpoint, int *multithreaded, void *user_data){    return fuse_setup_common(argc, argv, op, op_size, mountpoint,                             multithreaded, NULL, user_data, 0);}static void fuse_teardown_common(struct fuse *fuse, char *mountpoint){    struct fuse_session *se = fuse_get_session(fuse);    struct fuse_chan *ch = fuse_session_next_chan(se, NULL);    fuse_remove_signal_handlers(se);    fuse_unmount_common(mountpoint, ch);    fuse_destroy(fuse);    free(mountpoint);}void fuse_teardown(struct fuse *fuse, char *mountpoint){    fuse_teardown_common(fuse, mountpoint);}static int fuse_main_common(int argc, char *argv[],                            const struct fuse_operations *op, size_t op_size,                            void *user_data, int compat){    struct fuse *fuse;    char *mountpoint;    int multithreaded;    int res;    fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint,                             &multithreaded, NULL, user_data, compat);    if (fuse == NULL)        return 1;    if (multithreaded)        res = fuse_loop_mt(fuse);    else        res = fuse_loop(fuse);    fuse_teardown_common(fuse, mountpoint);    if (res == -1)        return 1;    return 0;}int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,                   size_t op_size, void *user_data){    return fuse_main_common(argc, argv, op, op_size, user_data, 0);}#undef fuse_mainint fuse_main(void);int fuse_main(void){    fprintf(stderr, "fuse_main(): This function does not exist\n");    return -1;}#include "fuse_compat.h"#ifndef __FreeBSD__struct fuse *fuse_setup_compat22(int argc, char *argv[],                                 const struct fuse_operations_compat22 *op,                                 size_t op_size, char **mountpoint,                                 int *multithreaded, int *fd){    return fuse_setup_common(argc, argv, (struct fuse_operations *) op,                             op_size, mountpoint, multithreaded, fd, NULL, 22);}struct fuse *fuse_setup_compat2(int argc, char *argv[],                                 const struct fuse_operations_compat2 *op,                                 char **mountpoint, int *multithreaded,                                 int *fd){    return fuse_setup_common(argc, argv, (struct fuse_operations *) op,                             sizeof(struct fuse_operations_compat2),                             mountpoint, multithreaded, fd, NULL, 21);}int fuse_main_real_compat22(int argc, char *argv[],                            const struct fuse_operations_compat22 *op,                            size_t op_size){    return fuse_main_common(argc, argv, (struct fuse_operations *) op, op_size,                            NULL, 22);}void fuse_main_compat1(int argc, char *argv[],                      const struct fuse_operations_compat1 *op){    fuse_main_common(argc, argv, (struct fuse_operations *) op,                     sizeof(struct fuse_operations_compat1), NULL, 11);}int fuse_main_compat2(int argc, char *argv[],                      const struct fuse_operations_compat2 *op){    return fuse_main_common(argc, argv, (struct fuse_operations *) op,                            sizeof(struct fuse_operations_compat2), NULL, 21);}int fuse_mount_compat1(const char *mountpoint, const char *args[]){    /* just ignore mount args for now */    (void) args;    return fuse_mount_compat22(mountpoint, NULL);}__asm__(".symver fuse_setup_compat2,__fuse_setup@");__asm__(".symver fuse_setup_compat22,fuse_setup@FUSE_2.2");__asm__(".symver fuse_teardown,__fuse_teardown@");__asm__(".symver fuse_main_compat2,fuse_main@");__asm__(".symver fuse_main_real_compat22,fuse_main_real@FUSE_2.2");#endif /* __FreeBSD__ */struct fuse *fuse_setup_compat25(int argc, char *argv[],                                 const struct fuse_operations_compat25 *op,                                 size_t op_size, char **mountpoint,                                 int *multithreaded, int *fd){    return fuse_setup_common(argc, argv, (struct fuse_operations *) op,                             op_size, mountpoint, multithreaded, fd, NULL, 25);}int fuse_main_real_compat25(int argc, char *argv[],                            const struct fuse_operations_compat25 *op,                            size_t op_size){    return fuse_main_common(argc, argv, (struct fuse_operations *) op, op_size,                            NULL, 25);}void fuse_teardown_compat22(struct fuse *fuse, int fd, char *mountpoint){    (void) fd;    fuse_teardown_common(fuse, mountpoint);}int fuse_mount_compat25(const char *mountpoint, struct fuse_args *args){    return fuse_kern_mount(mountpoint, args);}__asm__(".symver fuse_setup_compat25,fuse_setup@FUSE_2.5");__asm__(".symver fuse_teardown_compat22,fuse_teardown@FUSE_2.2");__asm__(".symver fuse_main_real_compat25,fuse_main_real@FUSE_2.5");__asm__(".symver fuse_mount_compat25,fuse_mount@FUSE_2.5");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -