[asterisk-commits] kpfleming: trunk r40769 - /trunk/main/loader.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Mon Aug 21 07:42:03 MST 2006
Author: kpfleming
Date: Mon Aug 21 09:42:03 2006
New Revision: 40769
URL: http://svn.digium.com/view/asterisk?rev=40769&view=rev
Log:
use a safer process for checking if a module wants to export symbols into the global namespace
Modified:
trunk/main/loader.c
Modified: trunk/main/loader.c
URL: http://svn.digium.com/view/asterisk/trunk/main/loader.c?rev=40769&r1=40768&r2=40769&view=diff
==============================================================================
--- trunk/main/loader.c (original)
+++ trunk/main/loader.c Mon Aug 21 09:42:03 2006
@@ -333,8 +333,8 @@
char fn[256];
void *lib;
struct ast_module *mod;
- unsigned int load_global = global_symbols_only;
char *resource = (char *) resource_in;
+ unsigned int wants_global;
if (strcasecmp(resource + strlen(resource) - 3, ".so")) {
resource = alloca(strlen(resource_in) + 3);
@@ -344,18 +344,16 @@
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)))
return NULL;
strcpy(resource_being_loaded->resource, resource);
- if (load_global)
- lib = dlopen(fn, RTLD_LAZY | RTLD_GLOBAL);
- else
- lib = dlopen(fn, RTLD_NOW | RTLD_LOCAL);
-
- if (!lib) {
+ if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) {
ast_log(LOG_WARNING, "%s\n", dlerror());
free(resource_being_loaded);
return NULL;
@@ -371,31 +369,43 @@
if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
/* no, it did not, so close it and return */
dlclose(lib);
+ /* note that the module's destructor will call ast_module_unregister(),
+ which will free the structure we allocated in resource_being_loaded */
+ 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;
+
+ /* if we are being asked only to load modules that provide global symbols,
+ and this one does not, then close it and return */
+ if (global_symbols_only && !wants_global)
+ return NULL;
+
+ /* start the load process again */
+
+ if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1)))
+ return NULL;
+
+ strcpy(resource_being_loaded->resource, resource);
+
+ 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;
}
+ /* 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;
- mod->lib = lib;
-
- /* if we are being asked only to load modules that provide global symbols,
- and this one does not, then close it and return */
- if (load_global && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) {
- unload_dynamic_module(mod);
- return NULL;
- }
-
- /* if we were not asked to load _only_ modules with global symbols, but
- this module wants to provide some, then we have to close and re-open
- in global mode
- */
- if (!load_global && ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) {
- unload_dynamic_module(mod);
- load_global = 1;
- goto tryload;
- }
-
- return mod;
+
+ return AST_LIST_LAST(&module_list);
}
#endif
More information about the asterisk-commits
mailing list