}
#ifdef LOADABLE_MODULES
+
+static void close_lib(const char *name, void *lib)
+{
+ char *error;
+
+ if (!lib) {
+ return;
+ }
+
+ /* Clear any existing error */
+ dlerror();
+ if (dlclose(lib)) {
+ error = dlerror();
+ ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n",
+ S_OR(name, "unknown"), S_OR(error, "Unknown error"));
+ }
+}
+
static void unload_dynamic_module(struct ast_module *mod)
{
void *lib = mod->lib;
/* WARNING: the structure pointed to by mod is going to
disappear when this operation succeeds, so we can't
dereference it */
-
- if (lib)
- while (!dlclose(lib));
+ close_lib(ast_module_name(mod), lib);
}
static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap, int required);
if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in);
/* no, it did not, so close it and return */
- while (!dlclose(lib));
+ close_lib(resource_in, 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;
/* 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) {
- while (!dlclose(lib));
+ close_lib(resource_in, lib);
return NULL;
}
}
#endif
- while (!dlclose(lib));
+ close_lib(resource_in, lib);
resource_being_loaded = NULL;
/* start the load process again */