blob: 89cd7a83af05874f9c510641d1f82d1bd3ea606b [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"
Miklos Szeredib75d4b92005-10-11 10:12:08 +000031 " -s disable multi-threaded operation\n"
Miklos Szeredifbb5c742005-02-09 15:47:51 +000032 " -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 }
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000277 return 0;
Miklos Szeredicc8c9752001-11-21 10:03:39 +0000278
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000279 err:
280 free(*kernel_opts);
281 free(*lib_opts);
282 free(*mountpoint);
283 return -1;
284}
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000285
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000286static struct fuse *fuse_setup_common(int argc, char *argv[],
287 const struct fuse_operations *op,
288 size_t op_size,
289 char **mountpoint,
290 int *multithreaded,
291 int *fd,
292 int compat)
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000293{
294 struct fuse *fuse;
295 int background;
296 char *kernel_opts;
297 char *lib_opts;
298 int res;
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000299
Miklos Szeredie175fb72004-10-21 16:33:17 +0000300 if (fuse_instance != NULL) {
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000301 fprintf(stderr, "fuse: fuse_setup() called twice\n");
Miklos Szeredie175fb72004-10-21 16:33:17 +0000302 return NULL;
303 }
304
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000305 res = fuse_parse_cmdline(argc, (const char **) argv, &kernel_opts,
306 &lib_opts, mountpoint, multithreaded,
307 &background);
308 if (res == -1)
309 return NULL;
310
311 *fd = fuse_mount(*mountpoint, kernel_opts);
312 if (*fd == -1)
313 goto err_free;
314
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000315 fuse = fuse_new_common(*fd, lib_opts, op, op_size, compat);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000316 if (fuse == NULL)
317 goto err_unmount;
318
Miklos Szeredi0f62d722005-01-04 12:45:54 +0000319 if (background && !opt_member(lib_opts, "debug")) {
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000320 res = daemon(0, 0);
321 if (res == -1) {
322 perror("fuse: failed to daemonize program\n");
323 goto err_destroy;
324 }
325 }
Miklos Szeredie175fb72004-10-21 16:33:17 +0000326
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000327 res = set_signal_handlers();
328 if (res == -1)
329 goto err_destroy;
330
Miklos Szeredicc82a8c2004-10-21 16:39:09 +0000331 fuse_instance = fuse;
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000332 free(kernel_opts);
333 free(lib_opts);
334 return fuse;
335
336 err_destroy:
337 fuse_destroy(fuse);
338 err_unmount:
339 fuse_unmount(*mountpoint);
340 err_free:
341 free(kernel_opts);
342 free(lib_opts);
343 free(*mountpoint);
344 return NULL;
345}
346
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000347struct fuse *fuse_setup(int argc, char *argv[],
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000348 const struct fuse_operations *op,
349 size_t op_size, char **mountpoint,
350 int *multithreaded, int *fd)
351{
352 return fuse_setup_common(argc, argv, op, op_size, mountpoint,
353 multithreaded, fd, 0);
354}
355
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000356struct fuse *fuse_setup_compat2(int argc, char *argv[],
357 const struct fuse_operations_compat2 *op,
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000358 char **mountpoint, int *multithreaded,
359 int *fd)
360{
Miklos Szeredie5183742005-02-02 11:14:04 +0000361 return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000362 sizeof(struct fuse_operations_compat2),
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000363 mountpoint, multithreaded, fd, 21);
364}
365
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000366void fuse_teardown(struct fuse *fuse, int fd, char *mountpoint)
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000367{
Miklos Szeredibcc53852005-11-10 09:54:41 +0000368 (void) fd;
369
Miklos Szeredie175fb72004-10-21 16:33:17 +0000370 if (fuse_instance != fuse)
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000371 fprintf(stderr, "fuse: fuse_teardown() with unknown fuse object\n");
Miklos Szeredie175fb72004-10-21 16:33:17 +0000372 else
373 fuse_instance = NULL;
374
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000375 fuse_destroy(fuse);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000376 fuse_unmount(mountpoint);
377 free(mountpoint);
378}
379
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000380static int fuse_main_common(int argc, char *argv[],
381 const struct fuse_operations *op, size_t op_size,
382 int compat)
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000383{
Miklos Szeredie175fb72004-10-21 16:33:17 +0000384 struct fuse *fuse;
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000385 char *mountpoint;
386 int multithreaded;
387 int res;
388 int fd;
389
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000390 fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint,
391 &multithreaded, &fd, compat);
Miklos Szeredie175fb72004-10-21 16:33:17 +0000392 if (fuse == NULL)
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000393 return 1;
Miklos Szeredie5183742005-02-02 11:14:04 +0000394
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000395 if (multithreaded)
Miklos Szeredie175fb72004-10-21 16:33:17 +0000396 res = fuse_loop_mt(fuse);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000397 else
Miklos Szeredie175fb72004-10-21 16:33:17 +0000398 res = fuse_loop(fuse);
Miklos Szeredie5183742005-02-02 11:14:04 +0000399
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000400 fuse_teardown(fuse, fd, mountpoint);
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000401 if (res == -1)
402 return 1;
Miklos Szeredie5183742005-02-02 11:14:04 +0000403
Miklos Szeredi5dc8a802004-10-21 09:35:10 +0000404 return 0;
Miklos Szeredicc8c9752001-11-21 10:03:39 +0000405}
406
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000407int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
408 size_t op_size)
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000409{
410 return fuse_main_common(argc, argv, op, op_size, 0);
411}
412
Miklos Szeredie56818b2004-12-12 11:45:24 +0000413#undef fuse_main
Miklos Szeredif6e0ec62005-08-03 09:11:06 +0000414int fuse_main(void)
Miklos Szeredie56818b2004-12-12 11:45:24 +0000415{
Miklos Szeredi3ead28e2005-01-18 21:23:41 +0000416 fprintf(stderr, "fuse_main(): This function does not exist\n");
Miklos Szeredie56818b2004-12-12 11:45:24 +0000417 return -1;
418}
419
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000420void fuse_main_compat1(int argc, char *argv[],
421 const struct fuse_operations_compat1 *op)
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000422{
Miklos Szeredie5183742005-02-02 11:14:04 +0000423 fuse_main_common(argc, argv, (struct fuse_operations *) op,
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000424 sizeof(struct fuse_operations_compat1), 11);
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000425}
426
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000427int fuse_main_compat2(int argc, char *argv[],
428 const struct fuse_operations_compat2 *op)
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000429{
430 return fuse_main_common(argc, argv, (struct fuse_operations *) op,
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000431 sizeof(struct fuse_operations_compat2), 21);
Miklos Szeredi0b6a0ad2004-12-04 00:40:50 +0000432}
433
Miklos Szeredif458b8c2004-12-07 16:46:42 +0000434__asm__(".symver fuse_setup_compat2,__fuse_setup@");
435__asm__(".symver fuse_teardown,__fuse_teardown@");
436__asm__(".symver fuse_main_compat2,fuse_main@");