Go to the source code of this file.
Data Structures | |
struct | egg_module |
Defines | |
#define | MODULE_USER 0 |
#define | MODULE_SHUTDOWN 1 |
#define | MODULE_RESTART 2 |
#define | BTN_LOAD_MODULE "load" |
#define | BTN_UNLOAD_MODULE "unload" |
#define | EXPORT_SCOPE |
Typedefs | |
typedef struct egg_module | egg_module_t |
typedef int(* | egg_start_func_t )(egg_module_t *modinfo) |
typedef int(* | egg_close_func_t )(int why) |
typedef void(* | egg_unload_func_t )(void) |
typedef void(* | egg_cleanup_hook_t )(egg_module_t *mod) |
Functions | |
int | module_init (void) |
int | module_shutdown (void) |
Shuts down the module interface. | |
int | module_add_dir (const char *moddir) |
int | module_load (const char *name) |
Load a module. | |
int | module_loaded (const char *name) |
int | module_unload (const char *name, int why) |
Unload a module. | |
egg_module_t * | module_lookup (const char *name) |
void * | module_get_api (const char *name, int major, int minor) |
int | module_addref (const char *name) |
int | module_decref (const char *name) |
int | module_list (const char ***names) |
#define BTN_LOAD_MODULE "load" |
#define BTN_UNLOAD_MODULE "unload" |
#define MODULE_RESTART 2 |
#define MODULE_SHUTDOWN 1 |
#define MODULE_USER 0 |
Definition at line 26 of file module.h.
Referenced by module_unload(), party_unloadmod(), and script_module_unload().
typedef void(* egg_cleanup_hook_t)(egg_module_t *mod) |
typedef int(* egg_close_func_t)(int why) |
typedef struct egg_module egg_module_t |
typedef int(* egg_start_func_t)(egg_module_t *modinfo) |
typedef void(* egg_unload_func_t)(void) |
int module_add_dir | ( | const char * | moddir | ) |
Definition at line 95 of file module.c.
References egg_mprintf().
Referenced by core_init().
00096 { 00097 char *fixed_moddir; 00098 00099 if (*moddir != '/') { 00100 char cwd[1024]; 00101 00102 cwd[0] = 0; 00103 getcwd(cwd, sizeof(cwd)); 00104 cwd[sizeof(cwd)-1] = 0; 00105 fixed_moddir = egg_mprintf("%s/%s", cwd, moddir); 00106 } 00107 else fixed_moddir = (char *)moddir; 00108 00109 lt_dladdsearchdir(fixed_moddir); 00110 if (fixed_moddir != moddir) free(fixed_moddir); 00111 return(0); 00112 }
int module_addref | ( | const char * | name | ) |
Definition at line 320 of file module.c.
References find_active_module, and module_list::refcount.
00321 { 00322 module_list_t *entry; 00323 00324 entry = find_active_module(name); 00325 if (!entry) return(-1); 00326 entry->refcount++; 00327 return(0); 00328 }
int module_decref | ( | const char * | name | ) |
Definition at line 330 of file module.c.
References find_active_module, and module_list::refcount.
00331 { 00332 module_list_t *entry; 00333 00334 entry = find_active_module(name); 00335 if (!entry) return(-1); 00336 entry->refcount--; 00337 return(0); 00338 }
void* module_get_api | ( | const char * | name, | |
int | major, | |||
int | minor | |||
) |
Definition at line 310 of file module.c.
References find_active_module, module_list::modinfo, egg_module::module_api, NULL, and module_list::refcount.
Referenced by chanserv_init().
00311 { 00312 module_list_t *entry; 00313 00314 entry = find_active_module(name); 00315 if (!entry) return(NULL); 00316 entry->refcount++; 00317 return entry->modinfo.module_api; 00318 }
int module_init | ( | void | ) |
Definition at line 54 of file module.c.
References bind_table_add(), BTN_LOAD_MODULE, BTN_UNLOAD_MODULE, and MATCH_MASK.
Referenced by eggdrop_init().
00055 { 00056 BT_load = bind_table_add(BTN_LOAD_MODULE, 1, "s", MATCH_MASK, 0); /* DDD */ 00057 BT_unload = bind_table_add(BTN_UNLOAD_MODULE, 2, "ss", MATCH_MASK, 0); /* DDD */ 00058 return(0); 00059 }
int module_list | ( | const char *** | names | ) |
Definition at line 340 of file module.c.
References module_list::modinfo, egg_module::name, module_list::next, and NULL.
Referenced by party_modules().
00341 { 00342 module_list_t *entry; 00343 int i = 0; 00344 00345 for (entry = module_list_head; entry; entry = entry->next) i++; 00346 *names = malloc((i + 1) * sizeof(char **)); 00347 i = 0; 00348 for (entry = module_list_head; entry; entry = entry->next) { 00349 (*names)[i] = entry->modinfo.name; 00350 i++; 00351 } 00352 (*names)[i] = NULL; 00353 return(i); 00354 }
int module_load | ( | const char * | name | ) |
Load a module.
This function loads a module and executes its start function. If the module name does not contain a path the default paths will be searched. If it does have an extenteion the plattforms default library extentions will be added.
name | The name of the module to load. |
-1 if the module is already loaded. (Nothing will be logged.)
-2 if the module could not be opened. (This will be logged.)
-3 if no start function is present. (Nothing will be logged.)
-4 if the start function returned an error. (Nothing will be logged.)
-5 if the module can't be loaded because it's marked for unloading. (Nothing will be logged.)
Definition at line 131 of file module.c.
References bind_check(), egg_mprintf(), find_active_module, find_deleted_module, module_list::hand, LOG_MISC, module_list::modinfo, module_list::next, NULL, module_list::prev, putlog(), and module_list::refcount.
Referenced by core_init(), and party_loadmod().
00132 { 00133 lt_dlhandle hand; 00134 module_list_t *entry; 00135 egg_start_func_t startfunc; 00136 char *startname; 00137 00138 00139 /* See if it's already loaded. */ 00140 entry = find_active_module(name); 00141 if (entry) return(-1); 00142 entry = find_deleted_module(name); 00143 if (entry) return(-5); 00144 00145 hand = lt_dlopenext(name); 00146 if (!hand) { 00147 const char *err = lt_dlerror(); 00148 putlog(LOG_MISC, "*", "Error loading module %s: %s", name, err); 00149 return(-2); 00150 } 00151 00152 startname = egg_mprintf("%s_LTX_start", name); 00153 startfunc = (egg_start_func_t)lt_dlsym(hand, startname); 00154 free(startname); 00155 if (!startfunc) { 00156 startfunc = (egg_start_func_t)lt_dlsym(hand, "start"); 00157 if (!startfunc) { 00158 lt_dlclose(hand); 00159 return(-3); 00160 } 00161 } 00162 00163 /* Create an entry for it. */ 00164 entry = calloc(1, sizeof(*entry)); 00165 entry->prev = NULL; 00166 entry->next = module_list_head; 00167 entry->refcount = 0; 00168 entry->hand = hand; 00169 module_list_head = entry; 00170 00171 if (startfunc(&entry->modinfo)) { 00172 module_list_head = module_list_head->next; 00173 free(entry); 00174 return(-4); 00175 } 00176 00177 putlog(LOG_MISC, "*", "Module loaded: %s", name); 00178 bind_check(BT_load, NULL, name, name); 00179 00180 return(0); 00181 }
int module_loaded | ( | const char * | name | ) |
Definition at line 303 of file module.c.
References find_active_module, and NULL.
00304 { 00305 if (name == NULL) return 0; 00306 00307 return (find_active_module(name) != NULL); 00308 }
egg_module_t* module_lookup | ( | const char * | name | ) |
Definition at line 294 of file module.c.
References find_active_module, module_list::modinfo, and NULL.
00295 { 00296 module_list_t *entry; 00297 00298 entry = find_active_module(name); 00299 if (entry) return(&entry->modinfo); 00300 return(NULL); 00301 }
int module_shutdown | ( | void | ) |
Shuts down the module interface.
This function unloads all loaded modules and deletes the load and unload bind tables.
The module_unload() function is called for every module that is currently loaded. If there is still a module loaded, for example because of dependencies, module_unload() is called again. This is done until either all modules have been unloaded or no more modules could be unloaded.
Definition at line 75 of file module.c.
References bind_table_del(), garbage_run(), module_list::modinfo, MODULE_RESTART, module_unload(), egg_module::name, and module_list::next.
Referenced by eggdrop_shutdown().
00076 { 00077 int unloaded; 00078 module_list_t *entry, *next; 00079 00080 do { 00081 unloaded = 0; 00082 for (entry = module_list_head; entry; entry = next) { 00083 next = entry->next; 00084 if (!module_unload(entry->modinfo.name, MODULE_RESTART)) unloaded = 1; 00085 } 00086 } while (unloaded); 00087 00088 bind_table_del(BT_load); 00089 bind_table_del(BT_unload); 00090 00091 garbage_run(); 00092 return (0); 00093 }
int module_unload | ( | const char * | name, | |
int | why | |||
) |
Unload a module.
If a module's reference count is 0 its closing function will be executed. If the closing function did not veto the unloading it will be removed from the list of active modules, the "unload" bind is triggered and a cleanup run is sceduled.
name | The name of the module to unload. | |
why | The reason this function was called: MODULE_USER, MODULE_RESTART or MODULE_SHUTDOWN. |
-1 if the module is not loaded. (Nothing will be logged.)
-2 if the module is in use by another module. (Nothing will be logged.)
-3 if the module's closing function vetoed. (Nothing will be logged.)
Definition at line 201 of file module.c.
References bind_check(), egg_module::close_func, deleted_head, find_active_module, garbage_add(), GARBAGE_ONCE, LOG_MISC, module_list::modinfo, module_cleanup(), MODULE_SHUTDOWN, MODULE_USER, module_list::next, NULL, module_list::prev, putlog(), and module_list::refcount.
Referenced by module_shutdown(), party_unloadmod(), and script_module_unload().
00202 { 00203 module_list_t *entry; 00204 int retval; 00205 00206 entry = find_active_module(name); 00207 if (!entry) return(-1); 00208 if (entry->refcount > 0) return(-2); 00209 if (entry->modinfo.close_func) { 00210 retval = entry->modinfo.close_func(why); 00211 if (retval) return(-3); 00212 } 00213 00214 if (entry->prev) entry->prev->next = entry->next; 00215 else module_list_head = entry->next; 00216 if (entry->next) entry->next->prev = entry->prev; 00217 00218 entry->next = NULL; 00219 if (!deleted_head) { 00220 deleted_head = entry; 00221 entry->prev = NULL; 00222 } else { 00223 module_list_t *tail; 00224 00225 for (tail = deleted_head; tail->next; tail = tail->next); 00226 tail->next = entry; 00227 entry->prev = tail; 00228 } 00229 00230 bind_check(BT_unload, NULL, name, name, why == MODULE_USER ? "request" : why == MODULE_SHUTDOWN ? "shutdown" : "restart"); 00231 putlog(LOG_MISC, "*", "Module unloaded: %s", name); 00232 garbage_add(module_cleanup, NULL, GARBAGE_ONCE); 00233 return 0; 00234 }