Package: fuse / 2.9.9-5

0005-dlsym.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
Author: Fabrice Bauzac <fbauzac@amadeus.com>
Description: fuse.c (fuse_load_so_name): use dlsym() instead of
 relying on ld.so constructor functions.

diff -Naurp fuse.orig/include/fuse.h fuse/include/fuse.h
--- fuse.orig/include/fuse.h
+++ fuse/include/fuse.h
@@ -956,13 +956,10 @@ void fuse_register_module(struct fuse_mo
  * For the parameters, see description of the fields in 'struct
  * fuse_module'
  */
-#define FUSE_REGISTER_MODULE(name_, factory_)				  \
-	static __attribute__((constructor)) void name_ ## _register(void) \
-	{								  \
-		static struct fuse_module mod =				  \
-			{ #name_, factory_, NULL, NULL, 0 };		  \
-		fuse_register_module(&mod);				  \
-	}
+#define FUSE_REGISTER_MODULE(name_, factory_)                           \
+        struct fuse_module fuse_fusemod_ ## name_ ## _module = {        \
+                #name_, factory_, NULL, NULL, 0                         \
+        };
 
 
 /* ----------------------------------------------------------- *
diff -Naurp fuse.orig/lib/fuse.c fuse/lib/fuse.c
--- fuse.orig/lib/fuse.c
+++ fuse/lib/fuse.c
@@ -218,41 +218,76 @@ struct fuse_context_i {
 	fuse_req_t req;
 };
 
+/* Defined by FUSE_REGISTER_MODULE() in lib/modules/subdir.c and iconv.c.  */
+extern struct fuse_module fuse_fusemod_subdir_module;
+extern struct fuse_module fuse_fusemod_iconv_module;
+
 static pthread_key_t fuse_context_key;
 static pthread_mutex_t fuse_context_lock = PTHREAD_MUTEX_INITIALIZER;
 static int fuse_context_ref;
 static struct fusemod_so *fuse_current_so;
-static struct fuse_module *fuse_modules;
+static struct fuse_module *fuse_modules = NULL;
 
-static int fuse_load_so_name(const char *soname)
+static int fuse_load_so_name(const char *soname, const char *module_name)
 {
 	struct fusemod_so *so;
+        int ret = 0;
 
 	so = calloc(1, sizeof(struct fusemod_so));
 	if (!so) {
 		fprintf(stderr, "fuse: memory allocation failed\n");
-		return -1;
+                ret = -1;
+                goto end;
 	}
 
 	fuse_current_so = so;
-	so->handle = dlopen(soname, RTLD_NOW);
+
+	so->handle = dlopen (soname, RTLD_NOW);
+        if (so->handle == NULL) {
+                fprintf (stderr, "fuse: dlopen() failed: %s\n", dlerror ());
+                ret = -1;
+                goto freeso_end;
+        }
+
+        const size_t module_len = strlen (module_name);
+        char *symbol = malloc (64 + module_len);
+        if (symbol == NULL) {
+                perror ("fuse");
+                ret = -1;
+                goto dlopen_end;
+        }
+
+        sprintf (symbol, "fuse_fusemod_%s_module", module_name);
+
+        struct fuse_module *module;
+        module = dlsym (so->handle, symbol);
+        if (module != NULL) {
+                fuse_register_module (module);
+        }
+
 	fuse_current_so = NULL;
-	if (!so->handle) {
-		fprintf(stderr, "fuse: %s\n", dlerror());
-		goto err;
-	}
+
 	if (!so->ctr) {
 		fprintf(stderr, "fuse: %s did not register any modules\n",
 			soname);
-		goto err;
+                ret = -1;
+		goto freesym_end;
 	}
-	return 0;
 
-err:
-	if (so->handle)
-		dlclose(so->handle);
-	free(so);
-	return -1;
+freesym_end:
+        free (symbol);
+dlopen_end:
+        if (ret != 0) {
+                /* dlclose() only on error, otherwise we won't have
+                 * access to the .so anymore.  */
+                if (dlclose (so->handle)) {
+                        fprintf (stderr, "fuse: dlclose() failed: %s\n", dlerror ());
+                }
+        }
+freeso_end:
+	free (so);
+end:
+	return ret;
 }
 
 static int fuse_load_so_module(const char *module)
@@ -264,14 +299,14 @@ static int fuse_load_so_module(const cha
 		return -1;
 	}
 	sprintf(soname, "libfusemod_%s.so", module);
-	res = fuse_load_so_name(soname);
+	res = fuse_load_so_name(soname, module);
 	free(soname);
 	return res;
 }
 
 static struct fuse_module *fuse_find_module(const char *module)
 {
-	struct fuse_module *m;
+        struct fuse_module *m;
 	for (m = fuse_modules; m; m = m->next) {
 		if (strcmp(module, m->name) == 0) {
 			m->ctr++;
@@ -4597,6 +4632,15 @@ struct fuse *fuse_new_common(struct fuse
 	struct fuse_fs *fs;
 	struct fuse_lowlevel_ops llop = fuse_path_ops;
 
+        /* Boolean: have the builtin modules already been registered?  */
+        static int builtin_modules_registered_p = 0;
+        if (builtin_modules_registered_p == 0) {
+                /* If not, register them. */
+                fuse_register_module (&fuse_fusemod_subdir_module);
+                fuse_register_module (&fuse_fusemod_iconv_module);
+                builtin_modules_registered_p = 1;
+        }
+
 	if (fuse_create_context_key() == -1)
 		goto out;