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 } |