25 |
25 |
26 return SUCCESS; |
26 return SUCCESS; |
27 } |
27 } |
28 |
28 |
29 /** |
29 /** |
30 * Load the symbol named "<module>_<suffix>", |
30 * Load the symbol named "<module>_<suffix>". |
31 */ |
31 */ |
32 static err_t module_symbol (struct module *module, void **sym, const char *suffix) |
32 static err_t module_symbol (struct module *module, void **sym, const char *suffix) |
33 { |
33 { |
34 char sym_name[MODULE_SYMBOL_MAX]; |
34 char sym_name[MODULE_SYMBOL_MAX]; |
35 |
35 |
36 // validate the length of the suffix |
36 // validate the length of the suffix |
|
37 assert(strlen(module->info.name) <= MODULE_NAME_MAX); |
37 assert(strlen(suffix) <= MODULE_SUFFIX_MAX); |
38 assert(strlen(suffix) <= MODULE_SUFFIX_MAX); |
38 |
39 |
39 // format |
40 // format |
40 sprintf(sym_name, "%s_%s", module->info.name, suffix); |
41 sprintf(sym_name, "%s_%s", module->info.name, suffix); |
41 |
42 |
42 // load |
43 // load |
43 if ((*sym = dlsym(module->handle, sym_name)) == NULL) { |
44 if ((*sym = dlsym(module->handle, sym_name)) == NULL) |
44 log_error("dlsym(%s, %s) failed: %s", module->info.name, sym_name, dlerror()); |
45 return ERR_MODULE_SYM; |
45 |
|
46 return ERR_MODULE_SYM; |
|
47 } |
|
48 |
46 |
49 // ok |
47 // ok |
50 return SUCCESS; |
48 return SUCCESS; |
51 } |
49 } |
52 |
50 |
53 err_t module_load (struct modules *modules, struct module **module_ptr, const struct module_info *info, struct error_info *err) |
51 err_t module_load (struct modules *modules, struct module **module_ptr, const struct module_info *info, struct error_info *err) |
54 { |
52 { |
55 struct module *module; |
53 struct module *module; |
56 module_init_func_t init_func; |
|
57 |
54 |
58 // validate the module name |
55 // validate the module name |
59 if (strlen(info->name) > MODULE_NAME_MAX) |
56 if (strlen(info->name) > MODULE_NAME_MAX) |
60 return SET_ERROR(err, ERR_MODULE_NAME); |
57 return SET_ERROR(err, ERR_MODULE_NAME); |
61 |
58 |
63 if ((module = calloc(1, sizeof(*module))) == NULL) |
60 if ((module = calloc(1, sizeof(*module))) == NULL) |
64 return SET_ERROR(err, ERR_CALLOC); |
61 return SET_ERROR(err, ERR_CALLOC); |
65 |
62 |
66 // store |
63 // store |
67 module->info = *info; |
64 module->info = *info; |
68 module->modules = modules; |
|
69 |
65 |
70 // clear dlerrors |
66 // clear dlerrors |
71 (void) dlerror(); |
67 (void) dlerror(); |
72 |
68 |
73 // load it |
69 // load it |
74 if ((module->handle = dlopen(info->path, RTLD_NOW)) == NULL) { |
70 if ((module->handle = dlopen(info->path, RTLD_NOW)) == NULL) |
75 log_error("dlopen(%s) failed: %s", info->path, dlerror()); |
71 JUMP_SET_ERROR_STR(err, ERR_MODULE_OPEN, dlerror()); |
|
72 |
|
73 // load the funcs symbol |
|
74 if ((ERROR_CODE(err) = module_symbol(module, (void **) &module->funcs, "funcs"))) |
|
75 JUMP_SET_ERROR_STR(err, ERROR_CODE(err), dlerror()); |
76 |
76 |
77 JUMP_SET_ERROR(err, ERR_MODULE_OPEN); |
77 // call the init func |
78 } |
78 if ((module->funcs->init(modules->nexus, &module->ctx, err))) |
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)) == NULL) { |
|
86 // ensure that this results in a valid error return code! |
|
87 assert(ERROR_CODE(err)); |
|
88 |
|
89 goto error; |
79 goto error; |
90 } |
|
91 |
80 |
92 // add to modules list |
81 // add to modules list |
93 TAILQ_INSERT_TAIL(&modules->list, module, modules_list); |
82 TAILQ_INSERT_TAIL(&modules->list, module, modules_list); |
94 |
83 |
95 // ok |
84 // ok |
104 return ERROR_CODE(err); |
93 return ERROR_CODE(err); |
105 } |
94 } |
106 |
95 |
107 err_t module_conf (struct module *module, const char *name, char *value, struct error_info *err) |
96 err_t module_conf (struct module *module, const char *name, char *value, struct error_info *err) |
108 { |
97 { |
109 module_conf_func_t conf_func; |
98 // call the conf func |
110 |
99 return module->funcs->conf(module->ctx, name, value, err); |
111 // load the conf symbol |
|
112 if ((ERROR_CODE(err) = module_symbol(module, (void *) &conf_func, "conf"))) |
|
113 return ERROR_CODE(err); |
|
114 |
|
115 // call it |
|
116 if (conf_func(module->ctx, name, value, err)) |
|
117 return ERROR_CODE(err); |
|
118 |
|
119 // ok |
|
120 return SUCCESS; |
|
121 } |
100 } |