mirror of
https://github.com/libfuse/libfuse.git
synced 2024-11-26 21:54:30 +08:00
cleanups + step minor version
This commit is contained in:
parent
a2c5e56bc0
commit
5dc8a80c65
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
244
lib/helper.c
244
lib/helper.c
@ -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()
|
||||
static int 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
fuse_fd = fuse_mount(fuse_mountpoint, kernel_opts);
|
||||
if (fuse_fd == -1)
|
||||
exit(1);
|
||||
if (kernel_opts)
|
||||
free(kernel_opts);
|
||||
return 0;
|
||||
|
||||
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);
|
||||
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_teardown(fuse_obj, fd, mountpoint);
|
||||
if (res == -1)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user