blob: 75959e20143977cd4dfbc94d880734678e1a39b7 [file] [log] [blame]
Miklos Szeredicc8c9752001-11-21 10:03:39 +00001/*
2 FUSE: Filesystem in Userspace
Miklos Szeredi149f6072005-01-10 12:29:28 +00003 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
Miklos Szeredicc8c9752001-11-21 10:03:39 +00004
Miklos Szeredi8b39a9f2002-10-25 12:41:16 +00005 This program can be distributed under the terms of the GNU LGPL.
6 See the file COPYING.LIB.
Miklos Szeredicc8c9752001-11-21 10:03:39 +00007*/
8
Miklos Szeredi178451d2005-08-15 13:19:07 +00009#include "fuse_i.h"
Miklos Szeredi0f62d722005-01-04 12:45:54 +000010#include "fuse_compat.h"
Miklos Szeredicc8c9752001-11-21 10:03:39 +000011
12#include <stdio.h>
13#include <stdlib.h>
Miklos Szeredicc8c9752001-11-21 10:03:39 +000014#include <unistd.h>
Miklos Szeredi0f48a262002-12-05 14:23:01 +000015#include <string.h>
Miklos Szeredicc8c9752001-11-21 10:03:39 +000016#include <limits.h>
17#include <signal.h>
Miklos Szeredicc8c9752001-11-21 10:03:39 +000018
Miklos Szeredie175fb72004-10-21 16:33:17 +000019static struct fuse *fuse_instance;
Miklos Szeredicc8c9752001-11-21 10:03:39 +000020
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000021static void usage(const char *progname)
Miklos Szeredicc8c9752001-11-21 10:03:39 +000022{
Miklos Szeredi799993c2004-12-04 21:20:05 +000023 if (progname)
24 fprintf(stderr,
25 "usage: %s mountpoint [FUSE options]\n\n", progname);
26
Miklos Szeredie5183742005-02-02 11:14:04 +000027 fprintf(stderr,
Miklos Szeredi799993c2004-12-04 21:20:05 +000028 "FUSE options:\n"
Miklos Szeredifbb5c742005-02-09 15:47:51 +000029 " -d enable debug output (implies -f)\n"
30 " -f foreground operation\n"
31 " -s disable multithreaded operation\n"
32 " -r mount read only (equivalent to '-o ro')\n"
33 " -o opt,[opt...] mount options\n"
34 " -h print help\n"
Miklos Szeredi307242f2004-01-26 11:28:44 +000035 "\n"
Miklos Szeredibd7661b2004-07-23 17:16:29 +000036 "Mount options:\n"
37 " default_permissions enable permission checking\n"
38 " allow_other allow access to other users\n"
Miklos Szeredi3c7d41b2005-01-09 20:05:27 +000039 " allow_root allow access to root\n"
Miklos Szeredibd7661b2004-07-23 17:16:29 +000040 " kernel_cache cache files in kernel\n"
41 " large_read issue large read requests (2.4 only)\n"
42 " direct_io use direct I/O\n"
43 " max_read=N set maximum size of read requests\n"
44 " hard_remove immediate removal (don't hide files)\n"
45 " debug enable debug output\n"
Miklos Szeredi830ef702005-02-10 19:39:34 +000046 " fsname=NAME set filesystem name in mtab\n"
Miklos Szeredi33be22d2005-05-27 09:12:43 +000047 " use_ino let filesystem set inode numbers\n"
48 " readdir_ino try to fill in d_ino in readdir\n"
Miklos Szeredi340d21f2005-07-06 10:07:52 +000049 " nonempty allow mounts over non-empty file/dir\n"
Miklos Szeredie331c4b2005-07-06 13:34:02 +000050 " umask=M set file permissions (octal)\n"
51 " uid=N set file owner\n"
52 " gid=N set file group\n"
Miklos Szeredi33be22d2005-05-27 09:12:43 +000053 );
Miklos Szeredicc8c9752001-11-21 10:03:39 +000054}
55
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000056static void invalid_option(const char *argv[], int argctr)
Miklos Szeredi307242f2004-01-26 11:28:44 +000057{
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000058 fprintf(stderr, "fuse: invalid option: %s\n\n", argv[argctr]);
Miklos Szeredid59bb9d2004-12-07 10:04:24 +000059 fprintf(stderr, "see `%s -h' for usage\n", argv[0]);
Miklos Szeredi307242f2004-01-26 11:28:44 +000060}
61
Miklos Szeredif6e0ec62005-08-03 09:11:06 +000062static void exit_handler(int sig)
Miklos Szeredicc8c9752001-11-21 10:03:39 +000063{
Miklos Szeredif6e0ec62005-08-03 09:11:06 +000064 (void) sig;
Miklos Szeredie175fb72004-10-21 16:33:17 +000065 if (fuse_instance != NULL)
66 fuse_exit(fuse_instance);
Miklos Szeredicc8c9752001-11-21 10:03:39 +000067}
68
Miklos Szeredif6e0ec62005-08-03 09:11:06 +000069static int set_one_signal_handler(int sig, void (*handler)(int))
Miklos Szeredicc8c9752001-11-21 10:03:39 +000070{
71 struct sigaction sa;
Miklos Szerediacb4d362004-07-02 16:20:45 +000072 struct sigaction old_sa;
Miklos Szeredicc8c9752001-11-21 10:03:39 +000073
Miklos Szeredie7d5d7d2004-07-16 18:27:50 +000074 memset(&sa, 0, sizeof(struct sigaction));
Miklos Szerediacb4d362004-07-02 16:20:45 +000075 sa.sa_handler = handler;
Miklos Szeredicc8c9752001-11-21 10:03:39 +000076 sigemptyset(&(sa.sa_mask));
77 sa.sa_flags = 0;
78
Miklos Szeredif6e0ec62005-08-03 09:11:06 +000079 if (sigaction(sig, NULL, &old_sa) == -1) {
Miklos Szerediacb4d362004-07-02 16:20:45 +000080 perror("FUSE: cannot get old signal handler");
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000081 return -1;
Miklos Szeredicc8c9752001-11-21 10:03:39 +000082 }
Miklos Szeredie5183742005-02-02 11:14:04 +000083
Miklos Szerediacb4d362004-07-02 16:20:45 +000084 if (old_sa.sa_handler == SIG_DFL &&
Miklos Szeredif6e0ec62005-08-03 09:11:06 +000085 sigaction(sig, &sa, NULL) == -1) {
Miklos Szerediacb4d362004-07-02 16:20:45 +000086 perror("Cannot set signal handler");
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000087 return -1;
Miklos Szerediacb4d362004-07-02 16:20:45 +000088 }
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000089 return 0;
Miklos Szerediacb4d362004-07-02 16:20:45 +000090}
Miklos Szeredicc8c9752001-11-21 10:03:39 +000091
Miklos Szeredif6e0ec62005-08-03 09:11:06 +000092static int set_signal_handlers(void)
Miklos Szerediacb4d362004-07-02 16:20:45 +000093{
Miklos Szeredi5dc8a802004-10-21 09:35:10 +000094 if (set_one_signal_handler(SIGHUP, exit_handler) == -1 ||
95 set_one_signal_handler(SIGINT, exit_handler) == -1 ||
96 set_one_signal_handler(SIGTERM, exit_handler) == -1 ||
97 set_one_signal_handler(SIGPIPE, SIG_IGN) == -1)
98 return -1;
Miklos Szerediba1e2dc2004-09-16 08:43:24 +000099
Miklos Szerediff875352004-06-03 13:52:40 +0000100 return 0;
101}
102
Miklos Szeredi0f62d722005-01-04 12:45:54 +0000103static int opt_member(const char *opts, const char *opt)
104{
105 const char *e, *s = opts;
106 int optlen = strlen(opt);
107 for (s = opts; s; s = e + 1) {
108 if(!(e = strchr(s, ',')))
109 break;
110 if (e - s == optlen && strncmp(s, opt, optlen) == 0)
111 return 1;
112 }
113 return (s && strcmp(s, opt) == 0);
114}
115
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000116static int add_option_to(const char *opt, char **optp)
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000117{
118 unsigned len = strlen(opt);
119 if (*optp) {
120 unsigned oldlen = strlen(*optp);
Miklos Szeredif6e0ec62005-08-03 09:11:06 +0000121 *optp = (char *) realloc(*optp, oldlen + 1 + len + 1);
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000122 if (*optp == NULL)
123 return -1;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000124 (*optp)[oldlen] = ',';
125 strcpy(*optp + oldlen + 1, opt);
126 } else {
Miklos Szeredif6e0ec62005-08-03 09:11:06 +0000127 *optp = (char *) malloc(len + 1);
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000128 if (*optp == NULL)
129 return -1;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000130 strcpy(*optp, opt);
131 }
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000132 return 0;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000133}
134
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000135static int add_options(char **lib_optp, char **kernel_optp, const char *opts)
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000136{
137 char *xopts = strdup(opts);
138 char *s = xopts;
139 char *opt;
Miklos Szeredic902a852005-07-07 12:35:37 +0000140 int has_allow_other = 0;
141 int has_allow_root = 0;
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000142
143 if (xopts == NULL) {
144 fprintf(stderr, "fuse: memory allocation failed\n");
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000145 return -1;
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000146 }
147
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000148 while((opt = strsep(&s, ",")) != NULL) {
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000149 int res;
Miklos Szeredi0111f9d2005-04-22 12:04:55 +0000150 if (fuse_is_lib_option(opt)) {
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000151 res = add_option_to(opt, lib_optp);
Miklos Szeredi0111f9d2005-04-22 12:04:55 +0000152 /* Compatibility hack */
Miklos Szeredic902a852005-07-07 12:35:37 +0000153 if (strcmp(opt, "allow_root") == 0 && res != -1) {
154 has_allow_root = 1;
Miklos Szeredi0111f9d2005-04-22 12:04:55 +0000155 res = add_option_to("allow_other", kernel_optp);
Miklos Szeredic902a852005-07-07 12:35:37 +0000156 }
Miklos Szeredi0111f9d2005-04-22 12:04:55 +0000157 }
Miklos Szeredic902a852005-07-07 12:35:37 +0000158 else {
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000159 res = add_option_to(opt, kernel_optp);
Miklos Szeredic902a852005-07-07 12:35:37 +0000160 if (strcmp(opt, "allow_other") == 0)
161 has_allow_other = 1;
162 }
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000163 if (res == -1) {
164 fprintf(stderr, "fuse: memory allocation failed\n");
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000165 return -1;
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000166 }
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000167 }
Miklos Szeredic902a852005-07-07 12:35:37 +0000168 if (has_allow_other && has_allow_root) {
169 fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
170 return -1;
171 }
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000172 free(xopts);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000173 return 0;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000174}
175
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000176static int fuse_parse_cmdline(int argc, const char *argv[], char **kernel_opts,
177 char **lib_opts, char **mountpoint,
178 int *multithreaded, int *background)
Miklos Szeredicc8c9752001-11-21 10:03:39 +0000179{
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000180 int res;
Miklos Szeredie970f302004-02-25 08:39:42 +0000181 int argctr;
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000182 const char *basename;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000183 char *fsname_opt;
Miklos Szeredie5183742005-02-02 11:14:04 +0000184
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000185 *kernel_opts = NULL;
186 *lib_opts = NULL;
187 *mountpoint = NULL;
188 *multithreaded = 1;
189 *background = 1;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000190
191 basename = strrchr(argv[0], '/');
192 if (basename == NULL)
193 basename = argv[0];
194 else if (basename[1] != '\0')
195 basename++;
196
Miklos Szeredif6e0ec62005-08-03 09:11:06 +0000197 fsname_opt = (char *) malloc(strlen(basename) + 64);
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000198 if (fsname_opt == NULL) {
199 fprintf(stderr, "fuse: memory allocation failed\n");
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000200 return -1;
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000201 }
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000202 sprintf(fsname_opt, "fsname=%s", basename);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000203 res = add_options(lib_opts, kernel_opts, fsname_opt);
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000204 free(fsname_opt);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000205 if (res == -1)
206 goto err;
Miklos Szeredie5183742005-02-02 11:14:04 +0000207
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000208 for (argctr = 1; argctr < argc; argctr ++) {
Miklos Szerediff875352004-06-03 13:52:40 +0000209 if (argv[argctr][0] == '-') {
210 if (strlen(argv[argctr]) == 2)
211 switch (argv[argctr][1]) {
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000212 case 'o':
213 if (argctr + 1 == argc || argv[argctr+1][0] == '-') {
Miklos Szeredi799993c2004-12-04 21:20:05 +0000214 fprintf(stderr, "missing option after -o\n");
Miklos Szeredid59bb9d2004-12-07 10:04:24 +0000215 fprintf(stderr, "see `%s -h' for usage\n", argv[0]);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000216 goto err;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000217 }
218 argctr ++;
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000219 res = add_options(lib_opts, kernel_opts, argv[argctr]);
220 if (res == -1)
221 goto err;
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000222 break;
Miklos Szeredie5183742005-02-02 11:14:04 +0000223
Miklos Szeredie970f302004-02-25 08:39:42 +0000224 case 'd':
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000225 res = add_options(lib_opts, kernel_opts, "debug");
226 if (res == -1)
227 goto err;
Miklos Szeredie970f302004-02-25 08:39:42 +0000228 break;
Miklos Szeredie5183742005-02-02 11:14:04 +0000229
Miklos Szeredi96dfad72004-11-30 00:00:02 +0000230 case 'r':
231 res = add_options(lib_opts, kernel_opts, "ro");
232 if (res == -1)
233 goto err;
234 break;
235
Miklos Szerediff875352004-06-03 13:52:40 +0000236 case 'f':
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000237 *background = 0;
Miklos Szerediff875352004-06-03 13:52:40 +0000238 break;
239
Miklos Szeredie970f302004-02-25 08:39:42 +0000240 case 's':
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000241 *multithreaded = 0;
Miklos Szeredie970f302004-02-25 08:39:42 +0000242 break;
Miklos Szeredie5183742005-02-02 11:14:04 +0000243
Miklos Szeredie970f302004-02-25 08:39:42 +0000244 case 'h':
245 usage(argv[0]);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000246 goto err;
Miklos Szeredie5183742005-02-02 11:14:04 +0000247
Miklos Szeredie970f302004-02-25 08:39:42 +0000248 default:
249 invalid_option(argv, argctr);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000250 goto err;
Miklos Szeredie970f302004-02-25 08:39:42 +0000251 }
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000252 else {
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000253 if (argv[argctr][1] == 'o') {
254 res = add_options(lib_opts, kernel_opts, &argv[argctr][2]);
255 if (res == -1)
256 goto err;
Miklos Szeredi799993c2004-12-04 21:20:05 +0000257 } else if(strcmp(argv[argctr], "-ho") == 0) {
258 usage(NULL);
259 goto err;
260 } else {
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000261 invalid_option(argv, argctr);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000262 goto err;
263 }
Miklos Szeredibd7661b2004-07-23 17:16:29 +0000264 }
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000265 } else if (*mountpoint == NULL) {
266 *mountpoint = strdup(argv[argctr]);
267 if (*mountpoint == NULL) {
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000268 fprintf(stderr, "fuse: memory allocation failed\n");
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000269 goto err;
Miklos Szeredib2cf9562004-09-16 08:42:40 +0000270 }
271 }
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000272 else {
Miklos Szeredi307242f2004-01-26 11:28:44 +0000273 invalid_option(argv, argctr);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000274 goto err;
275 }
Miklos Szeredi307242f2004-01-26 11:28:44 +0000276 }
277
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000278 if (*mountpoint == NULL) {
Miklos Szeredi799993c2004-12-04 21:20:05 +0000279 fprintf(stderr, "missing mountpoint\n");
Miklos Szeredid59bb9d2004-12-07 10:04:24 +0000280 fprintf(stderr, "see `%s -h' for usage\n", argv[0]);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000281 goto err;
Miklos Szeredie970f302004-02-25 08:39:42 +0000282 }
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000283 return 0;
Miklos Szeredicc8c9752001-11-21 10:03:39 +0000284
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000285 err:
286 free(*kernel_opts);
287 free(*lib_opts);
288 free(*mountpoint);
289 return -1;
290}
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000291
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000292static struct fuse *fuse_setup_common(int argc, char *argv[],
293 const struct fuse_operations *op,
294 size_t op_size,
295 char **mountpoint,
296 int *multithreaded,
297 int *fd,
298 int compat)
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000299{
300 struct fuse *fuse;
301 int background;
302 char *kernel_opts;
303 char *lib_opts;
304 int res;
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000305
Miklos Szeredie175fb72004-10-21 16:33:17 +0000306 if (fuse_instance != NULL) {
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000307 fprintf(stderr, "fuse: fuse_setup() called twice\n");
Miklos Szeredie175fb72004-10-21 16:33:17 +0000308 return NULL;
309 }
310
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000311 res = fuse_parse_cmdline(argc, (const char **) argv, &kernel_opts,
312 &lib_opts, mountpoint, multithreaded,
313 &background);
314 if (res == -1)
315 return NULL;
316
317 *fd = fuse_mount(*mountpoint, kernel_opts);
318 if (*fd == -1)
319 goto err_free;
320
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000321 fuse = fuse_new_common(*fd, lib_opts, op, op_size, compat);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000322 if (fuse == NULL)
323 goto err_unmount;
324
Miklos Szeredi0f62d722005-01-04 12:45:54 +0000325 if (background && !opt_member(lib_opts, "debug")) {
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000326 res = daemon(0, 0);
327 if (res == -1) {
328 perror("fuse: failed to daemonize program\n");
329 goto err_destroy;
330 }
331 }
Miklos Szeredie175fb72004-10-21 16:33:17 +0000332
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000333 res = set_signal_handlers();
334 if (res == -1)
335 goto err_destroy;
336
Miklos Szeredicc82a8c2004-10-21 16:39:09 +0000337 fuse_instance = fuse;
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000338 free(kernel_opts);
339 free(lib_opts);
340 return fuse;
341
342 err_destroy:
343 fuse_destroy(fuse);
344 err_unmount:
345 fuse_unmount(*mountpoint);
346 err_free:
347 free(kernel_opts);
348 free(lib_opts);
349 free(*mountpoint);
350 return NULL;
351}
352
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000353struct fuse *fuse_setup(int argc, char *argv[],
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000354 const struct fuse_operations *op,
355 size_t op_size, char **mountpoint,
356 int *multithreaded, int *fd)
357{
358 return fuse_setup_common(argc, argv, op, op_size, mountpoint,
359 multithreaded, fd, 0);
360}
361
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000362struct fuse *fuse_setup_compat2(int argc, char *argv[],
363 const struct fuse_operations_compat2 *op,
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000364 char **mountpoint, int *multithreaded,
365 int *fd)
366{
Miklos Szeredie5183742005-02-02 11:14:04 +0000367 return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000368 sizeof(struct fuse_operations_compat2),
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000369 mountpoint, multithreaded, fd, 21);
370}
371
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000372void fuse_teardown(struct fuse *fuse, int fd, char *mountpoint)
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000373{
Miklos Szeredie175fb72004-10-21 16:33:17 +0000374 if (fuse_instance != fuse)
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000375 fprintf(stderr, "fuse: fuse_teardown() with unknown fuse object\n");
Miklos Szeredie175fb72004-10-21 16:33:17 +0000376 else
377 fuse_instance = NULL;
378
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000379 fuse_destroy(fuse);
380 close(fd);
381 fuse_unmount(mountpoint);
382 free(mountpoint);
383}
384
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000385static int fuse_main_common(int argc, char *argv[],
386 const struct fuse_operations *op, size_t op_size,
387 int compat)
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000388{
Miklos Szeredie175fb72004-10-21 16:33:17 +0000389 struct fuse *fuse;
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000390 char *mountpoint;
391 int multithreaded;
392 int res;
393 int fd;
394
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000395 fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint,
396 &multithreaded, &fd, compat);
Miklos Szeredie175fb72004-10-21 16:33:17 +0000397 if (fuse == NULL)
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000398 return 1;
Miklos Szeredie5183742005-02-02 11:14:04 +0000399
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000400 if (multithreaded)
Miklos Szeredie175fb72004-10-21 16:33:17 +0000401 res = fuse_loop_mt(fuse);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000402 else
Miklos Szeredie175fb72004-10-21 16:33:17 +0000403 res = fuse_loop(fuse);
Miklos Szeredie5183742005-02-02 11:14:04 +0000404
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000405 fuse_teardown(fuse, fd, mountpoint);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000406 if (res == -1)
407 return 1;
Miklos Szeredie5183742005-02-02 11:14:04 +0000408
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000409 return 0;
Miklos Szeredicc8c9752001-11-21 10:03:39 +0000410}
411
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000412int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
413 size_t op_size)
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000414{
415 return fuse_main_common(argc, argv, op, op_size, 0);
416}
417
Miklos Szeredie56818b2004-12-12 11:45:24 +0000418#undef fuse_main
Miklos Szeredif6e0ec62005-08-03 09:11:06 +0000419int fuse_main(void)
Miklos Szeredie56818b2004-12-12 11:45:24 +0000420{
Miklos Szeredi3ead28e2005-01-18 21:23:41 +0000421 fprintf(stderr, "fuse_main(): This function does not exist\n");
Miklos Szeredie56818b2004-12-12 11:45:24 +0000422 return -1;
423}
424
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000425void fuse_main_compat1(int argc, char *argv[],
426 const struct fuse_operations_compat1 *op)
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000427{
Miklos Szeredie5183742005-02-02 11:14:04 +0000428 fuse_main_common(argc, argv, (struct fuse_operations *) op,
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000429 sizeof(struct fuse_operations_compat1), 11);
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000430}
431
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000432int fuse_main_compat2(int argc, char *argv[],
433 const struct fuse_operations_compat2 *op)
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000434{
435 return fuse_main_common(argc, argv, (struct fuse_operations *) op,
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000436 sizeof(struct fuse_operations_compat2), 21);
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000437}
438
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000439__asm__(".symver fuse_setup_compat2,__fuse_setup@");
440__asm__(".symver fuse_teardown,__fuse_teardown@");
441__asm__(".symver fuse_main_compat2,fuse_main@");