mirror of https://gitee.com/openkylin/fuse.git
fuse.c (fuse_load_so_name): use dlsym() instead of
relying on ld.so constructor functions. Gbp-Pq: Name 0005-dlsym.patch
This commit is contained in:
parent
3b95fe7d8b
commit
7670e8008a
|
@ -959,13 +959,10 @@ void fuse_register_module(struct fuse_module *mod);
|
|||
* 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 \
|
||||
};
|
||||
|
||||
|
||||
/* ----------------------------------------------------------- *
|
||||
|
|
78
lib/fuse.c
78
lib/fuse.c
|
@ -219,41 +219,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)
|
||||
|
@ -265,14 +300,14 @@ static int fuse_load_so_module(const char *module)
|
|||
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++;
|
||||
|
@ -4672,6 +4707,15 @@ struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
|
|||
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue