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;
|