src/module.c
branchmodules
changeset 55 6f7f6ae729d0
parent 54 9f74e924b01a
child 56 942370000450
equal deleted inserted replaced
54:9f74e924b01a 55:6f7f6ae729d0
     1 #include "module.h"
     1 #include "module.h"
       
     2 #include "log.h"
     2 
     3 
     3 #include <stdlib.h>
     4 #include <stdlib.h>
     4 #include <dlfcn.h>
     5 #include <dlfcn.h>
       
     6 #include <string.h>
       
     7 #include <assert.h>
     5 
     8 
     6 err_t modules_create (struct modules **modules_ptr, struct nexus *nexus)
     9 err_t modules_create (struct modules **modules_ptr, struct nexus *nexus)
     7 {
    10 {
     8     struct moduels *modules;
    11     struct modules *modules;
     9 
    12 
    10     // alloc
    13     // alloc
    11     if ((modules = calloc(1, sizeof(*modules))) == NULL)
    14     if ((modules = calloc(1, sizeof(*modules))) == NULL)
    12         return ERR_CALLOC;
    15         return ERR_CALLOC;
    13     
    16     
    14     // init
    17     // init
    15     TAILQ_INIT
    18     TAILQ_INIT(&modules->list);
    16 
    19 
    17     // store
    20     // store
    18     modules->nexus = nexus;
    21     modules->nexus = nexus;
       
    22 
       
    23     // ok
       
    24     *modules_ptr = modules;
       
    25 
       
    26     return SUCCESS;
    19 }
    27 }
    20 
    28 
    21 err_t module_load (struct module **module_ptr, struct nexus *nexus, const struct module_info *info, struct error_info *err)
    29 /**
       
    30  * Load the symbol named "<module>_<suffix>", 
       
    31  */ 
       
    32 static err_t module_symbol (struct module *module, void **sym, const char *suffix)
       
    33 {
       
    34     char sym_name[MODULE_SYMBOL_MAX];
       
    35 
       
    36     // validate the length of the suffix
       
    37     assert(strlen(suffix) <= MODULE_SUFFIX_MAX);
       
    38 
       
    39     // format
       
    40     sprintf(sym_name, "%s_%s", module->info.name, suffix);
       
    41 
       
    42     // load
       
    43     if ((*sym = dlsym(module->handle, sym_name)) == NULL) {
       
    44         log_error("dlsym(%s, %s) failed: %s", module->info.name, sym_name, dlerror());
       
    45 
       
    46         return ERR_MODULE_SYM;
       
    47     }
       
    48 
       
    49     // ok
       
    50     return SUCCESS;
       
    51 }
       
    52 
       
    53 err_t module_load (struct modules *modules, struct module **module_ptr, const struct module_info *info, struct error_info *err)
    22 {
    54 {
    23     struct module *module;
    55     struct module *module;
       
    56     module_init_func_t init_func;
    24 
    57 
       
    58     // validate the module name
       
    59     if (strlen(info->name) > MODULE_NAME_MAX)
       
    60         return SET_ERROR(err, ERR_MODULE_NAME);
       
    61     
       
    62     // alloc
       
    63     if ((module = calloc(1, sizeof(*module))) == NULL)
       
    64         return SET_ERROR(err, ERR_CALLOC);
       
    65     
       
    66     // store
       
    67     module->info = *info;
       
    68     module->modules = modules;
    25 
    69 
       
    70     // clear dlerrors
       
    71     (void) dlerror();
       
    72 
       
    73     // load it
       
    74     if ((module->handle = dlopen(info->path, RTLD_NOW)) == NULL) {
       
    75         log_error("dlopen(%s) failed: %s", info->path, dlerror());
       
    76 
       
    77         JUMP_SET_ERROR(err, ERR_MODULE_OPEN);
       
    78     }
       
    79     
       
    80     // load the init symbol    
       
    81     if ((ERROR_CODE(err) = module_symbol(module, (void *) &init_func, "init")))
       
    82         JUMP_SET_ERROR(err, ERR_MODULE_INIT_FUNC);
       
    83 
       
    84     // call it
       
    85     if ((module->ctx = init_func(modules, err)))
       
    86         goto error;
       
    87 
       
    88     // add to modules list
       
    89     TAILQ_INSERT_TAIL(&modules->list, module, modules_list);
       
    90 
       
    91     // ok
       
    92     *module_ptr = module;
       
    93 
       
    94     return SUCCESS;
       
    95 
       
    96 error:
       
    97     // XXX: cleanup
       
    98     free(module);
       
    99 
       
   100     return ERROR_CODE(err);    
    26 }
   101 }
       
   102 
       
   103 err_t module_conf (struct module *module, const char *name, char *value)
       
   104 {
       
   105     module_conf_func_t conf_func;
       
   106     err_t err;
       
   107 
       
   108     // load the conf symbol
       
   109     if ((err = module_symbol(module, (void *) &conf_func, "conf")))
       
   110         return err;
       
   111 
       
   112     // call it
       
   113     if ((err = conf_func(module, name, value)))
       
   114         return err;
       
   115 
       
   116     // ok
       
   117     return SUCCESS;
       
   118 }