libfuse/lib/helper.c

144 lines
3.1 KiB
C
Raw Normal View History

2001-11-21 18:03:39 +08:00
/*
FUSE: Filesystem in Userspace
Copyright (C) 2001 Miklos Szeredi (mszeredi@inf.bme.hu)
2002-10-25 20:41:16 +08:00
This program can be distributed under the terms of the GNU LGPL.
See the file COPYING.LIB.
2001-11-21 18:03:39 +08:00
*/
#include "fuse.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
2002-12-05 22:23:01 +08:00
#include <string.h>
2001-11-21 18:03:39 +08:00
#include <limits.h>
#include <signal.h>
2002-10-25 19:40:14 +08:00
#define FUSE_MOUNTED_ENV "_FUSE_MOUNTED"
#define FUSE_UMOUNT_CMD_ENV "_FUSE_UNMOUNT_CMD"
2002-12-05 22:23:01 +08:00
static struct fuse *fuse;
2001-11-21 18:03:39 +08:00
static void usage(char *progname)
{
fprintf(stderr,
"usage: %s mountpoint [options] \n"
"Options:\n"
" -d enable debug output\n"
" -s disable multithreaded operation\n"
" -h print help\n",
progname);
exit(1);
}
static void exit_handler()
{
2002-12-05 22:23:01 +08:00
if(fuse != NULL)
fuse_exit(fuse);
2001-11-21 18:03:39 +08:00
}
static void set_signal_handlers()
{
struct sigaction sa;
sa.sa_handler = exit_handler;
sigemptyset(&(sa.sa_mask));
sa.sa_flags = 0;
if (sigaction(SIGHUP, &sa, NULL) == -1 ||
sigaction(SIGINT, &sa, NULL) == -1 ||
sigaction(SIGTERM, &sa, NULL) == -1) {
perror("Cannot set exit signal handlers");
exit(1);
}
sa.sa_handler = SIG_IGN;
if(sigaction(SIGPIPE, &sa, NULL) == -1) {
perror("Cannot set ignored signals");
exit(1);
}
}
void fuse_main(int argc, char *argv[], const struct fuse_operations *op)
{
2002-10-25 19:40:14 +08:00
int argctr = 1;
2001-11-21 18:03:39 +08:00
int flags;
int multithreaded;
2002-10-25 19:40:14 +08:00
char *isreexec = getenv(FUSE_MOUNTED_ENV);
2002-12-05 22:23:01 +08:00
int fuse_fd;
char *fuse_mountpoint = NULL;
char umount_cmd[1024] = "";
2001-11-21 18:03:39 +08:00
2002-10-25 19:40:14 +08:00
if(isreexec == NULL) {
if(argc < 2 || argv[1][0] == '-')
usage(argv[0]);
2002-12-05 22:23:01 +08:00
fuse_mountpoint = strdup(argv[1]);
fuse_fd = fuse_mount(fuse_mountpoint, NULL);
2002-10-25 19:40:14 +08:00
if(fuse_fd == -1)
exit(1);
argctr++;
}
else {
char *tmpstr;
/* Old (obsolescent) way of doing the mount:
fusermount [options] mountpoint [program [args ...]]
fusermount execs this program and passes the control file
descriptor dup()-ed to stdin */
fuse_fd = 0;
tmpstr = getenv(FUSE_UMOUNT_CMD_ENV);
if(tmpstr != NULL)
strncpy(umount_cmd, tmpstr, sizeof(umount_cmd) - 1);
}
2001-11-21 18:03:39 +08:00
set_signal_handlers();
flags = 0;
multithreaded = 1;
for(; argctr < argc && argv[argctr][0] == '-'; argctr ++) {
switch(argv[argctr][1]) {
case 'd':
flags |= FUSE_DEBUG;
break;
case 's':
multithreaded = 0;
break;
case 'h':
usage(argv[0]);
break;
default:
fprintf(stderr, "invalid option: %s\n", argv[argctr]);
exit(1);
}
}
if(argctr != argc) {
fprintf(stderr, "missing or surplus argument\n");
exit(1);
}
2002-10-25 19:40:14 +08:00
fuse = fuse_new(fuse_fd, flags, op);
2001-11-21 18:03:39 +08:00
if(multithreaded)
fuse_loop_mt(fuse);
else
fuse_loop(fuse);
2002-12-05 22:23:01 +08:00
close(fuse_fd);
if(fuse_mountpoint != NULL)
fuse_unmount(fuse_mountpoint);
else if(umount_cmd[0] != '\0')
system(umount_cmd);
2001-11-21 18:03:39 +08:00
}