|
|
|
@ -333,8 +333,8 @@ static struct ast_module *load_dynamic_module(const char *resource_in, unsigned
|
|
|
|
char fn[256];
|
|
|
|
char fn[256];
|
|
|
|
void *lib;
|
|
|
|
void *lib;
|
|
|
|
struct ast_module *mod;
|
|
|
|
struct ast_module *mod;
|
|
|
|
unsigned int load_global = global_symbols_only;
|
|
|
|
|
|
|
|
char *resource = (char *) resource_in;
|
|
|
|
char *resource = (char *) resource_in;
|
|
|
|
|
|
|
|
unsigned int wants_global;
|
|
|
|
|
|
|
|
|
|
|
|
if (strcasecmp(resource + strlen(resource) - 3, ".so")) {
|
|
|
|
if (strcasecmp(resource + strlen(resource) - 3, ".so")) {
|
|
|
|
resource = alloca(strlen(resource_in) + 3);
|
|
|
|
resource = alloca(strlen(resource_in) + 3);
|
|
|
|
@ -344,18 +344,16 @@ static struct ast_module *load_dynamic_module(const char *resource_in, unsigned
|
|
|
|
|
|
|
|
|
|
|
|
snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR, resource);
|
|
|
|
snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR, resource);
|
|
|
|
|
|
|
|
|
|
|
|
tryload:
|
|
|
|
/* make a first load of the module in 'quiet' mode... don't try to resolve
|
|
|
|
|
|
|
|
any symbols, and don't export any symbols. this will allow us to peek into
|
|
|
|
|
|
|
|
the module's info block (if available) to see what flags it has set */
|
|
|
|
|
|
|
|
|
|
|
|
if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1)))
|
|
|
|
if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1)))
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
strcpy(resource_being_loaded->resource, resource);
|
|
|
|
strcpy(resource_being_loaded->resource, resource);
|
|
|
|
|
|
|
|
|
|
|
|
if (load_global)
|
|
|
|
if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) {
|
|
|
|
lib = dlopen(fn, RTLD_LAZY | RTLD_GLOBAL);
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
lib = dlopen(fn, RTLD_NOW | RTLD_LOCAL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!lib) {
|
|
|
|
|
|
|
|
ast_log(LOG_WARNING, "%s\n", dlerror());
|
|
|
|
ast_log(LOG_WARNING, "%s\n", dlerror());
|
|
|
|
free(resource_being_loaded);
|
|
|
|
free(resource_being_loaded);
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
@ -371,31 +369,43 @@ tryload:
|
|
|
|
if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
|
|
|
|
if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
|
|
|
|
/* no, it did not, so close it and return */
|
|
|
|
/* no, it did not, so close it and return */
|
|
|
|
dlclose(lib);
|
|
|
|
dlclose(lib);
|
|
|
|
free(resource_being_loaded);
|
|
|
|
/* note that the module's destructor will call ast_module_unregister(),
|
|
|
|
|
|
|
|
which will free the structure we allocated in resource_being_loaded */
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* we are done with this first load, so clean up and start over */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dlclose(lib);
|
|
|
|
resource_being_loaded = NULL;
|
|
|
|
resource_being_loaded = NULL;
|
|
|
|
mod->lib = lib;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* if we are being asked only to load modules that provide global symbols,
|
|
|
|
/* if we are being asked only to load modules that provide global symbols,
|
|
|
|
and this one does not, then close it and return */
|
|
|
|
and this one does not, then close it and return */
|
|
|
|
if (load_global && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) {
|
|
|
|
if (global_symbols_only && !wants_global)
|
|
|
|
unload_dynamic_module(mod);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* if we were not asked to load _only_ modules with global symbols, but
|
|
|
|
/* start the load process again */
|
|
|
|
this module wants to provide some, then we have to close and re-open
|
|
|
|
|
|
|
|
in global mode
|
|
|
|
if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1)))
|
|
|
|
*/
|
|
|
|
return NULL;
|
|
|
|
if (!load_global && ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) {
|
|
|
|
|
|
|
|
unload_dynamic_module(mod);
|
|
|
|
strcpy(resource_being_loaded->resource, resource);
|
|
|
|
load_global = 1;
|
|
|
|
|
|
|
|
goto tryload;
|
|
|
|
if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
|
|
|
|
|
|
|
|
ast_log(LOG_WARNING, "%s\n", dlerror());
|
|
|
|
|
|
|
|
free(resource_being_loaded);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return mod;
|
|
|
|
/* since the module was successfully opened, and it registered itself
|
|
|
|
|
|
|
|
the previous time we did that, we're going to assume it worked this
|
|
|
|
|
|
|
|
time too :) */
|
|
|
|
|
|
|
|
AST_LIST_LAST(&module_list)->lib = lib;
|
|
|
|
|
|
|
|
resource_being_loaded = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return AST_LIST_LAST(&module_list);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|