--- a/src/module.c Fri Mar 13 17:38:23 2009 +0200
+++ b/src/module.c Sun Mar 15 01:17:22 2009 +0200
@@ -1,26 +1,118 @@
#include "module.h"
+#include "log.h"
#include <stdlib.h>
#include <dlfcn.h>
+#include <string.h>
+#include <assert.h>
err_t modules_create (struct modules **modules_ptr, struct nexus *nexus)
{
- struct moduels *modules;
+ struct modules *modules;
// alloc
if ((modules = calloc(1, sizeof(*modules))) == NULL)
return ERR_CALLOC;
// init
- TAILQ_INIT
+ TAILQ_INIT(&modules->list);
// store
modules->nexus = nexus;
+
+ // ok
+ *modules_ptr = modules;
+
+ return SUCCESS;
}
-err_t module_load (struct module **module_ptr, struct nexus *nexus, const struct module_info *info, struct error_info *err)
+/**
+ * Load the symbol named "<module>_<suffix>",
+ */
+static err_t module_symbol (struct module *module, void **sym, const char *suffix)
+{
+ char sym_name[MODULE_SYMBOL_MAX];
+
+ // validate the length of the suffix
+ assert(strlen(suffix) <= MODULE_SUFFIX_MAX);
+
+ // format
+ sprintf(sym_name, "%s_%s", module->info.name, suffix);
+
+ // load
+ if ((*sym = dlsym(module->handle, sym_name)) == NULL) {
+ log_error("dlsym(%s, %s) failed: %s", module->info.name, sym_name, dlerror());
+
+ return ERR_MODULE_SYM;
+ }
+
+ // ok
+ return SUCCESS;
+}
+
+err_t module_load (struct modules *modules, struct module **module_ptr, const struct module_info *info, struct error_info *err)
{
struct module *module;
+ module_init_func_t init_func;
+ // validate the module name
+ if (strlen(info->name) > MODULE_NAME_MAX)
+ return SET_ERROR(err, ERR_MODULE_NAME);
+
+ // alloc
+ if ((module = calloc(1, sizeof(*module))) == NULL)
+ return SET_ERROR(err, ERR_CALLOC);
+
+ // store
+ module->info = *info;
+ module->modules = modules;
+ // clear dlerrors
+ (void) dlerror();
+
+ // load it
+ if ((module->handle = dlopen(info->path, RTLD_NOW)) == NULL) {
+ log_error("dlopen(%s) failed: %s", info->path, dlerror());
+
+ JUMP_SET_ERROR(err, ERR_MODULE_OPEN);
+ }
+
+ // load the init symbol
+ if ((ERROR_CODE(err) = module_symbol(module, (void *) &init_func, "init")))
+ JUMP_SET_ERROR(err, ERR_MODULE_INIT_FUNC);
+
+ // call it
+ if ((module->ctx = init_func(modules, err)))
+ goto error;
+
+ // add to modules list
+ TAILQ_INSERT_TAIL(&modules->list, module, modules_list);
+
+ // ok
+ *module_ptr = module;
+
+ return SUCCESS;
+
+error:
+ // XXX: cleanup
+ free(module);
+
+ return ERROR_CODE(err);
}
+
+err_t module_conf (struct module *module, const char *name, char *value)
+{
+ module_conf_func_t conf_func;
+ err_t err;
+
+ // load the conf symbol
+ if ((err = module_symbol(module, (void *) &conf_func, "conf")))
+ return err;
+
+ // call it
+ if ((err = conf_func(module, name, value)))
+ return err;
+
+ // ok
+ return SUCCESS;
+}