Releasing debian version 5.00+dfsg-1.
[syslinux-debian/hramrach.git] / com32 / lib / sys / module / exec.c
blob559bafc7a6e90803ada2412d6754a7b0908dc47f
1 /*
2 * exec.c
4 * Created on: Aug 14, 2008
5 * Author: Stefan Bucur <stefanb@zytor.com>
6 */
8 #include <sys/module.h>
9 #include <sys/exec.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdarg.h>
14 #include <setjmp.h>
15 #include <setjmp.h>
16 #include <alloca.h>
17 #include <dprintf.h>
19 #define DBG_PRINT(fmt, args...) dprintf("[EXEC] " fmt, ##args)
21 static struct elf_module *mod_root = NULL;
22 struct elf_module *__syslinux_current = NULL;
24 int exec_init(void)
26 int res;
28 res = modules_init();
29 if (res != 0)
30 return res;
32 // Load the root module
33 mod_root = module_alloc(EXEC_ROOT_NAME);
35 if (mod_root == NULL)
36 return -1;
38 res = module_load_shallow(mod_root, 0);
39 if (res != 0) {
40 mod_root = NULL;
41 return res;
44 return 0;
47 int get_module_type(struct elf_module *module)
49 if(module->main_func) return EXEC_MODULE;
50 return LIB_MODULE;
53 jmp_buf __process_exit_jmp;
55 #if 0
56 int spawnv(const char *name, const char **argv)
58 int res, ret_val = 0;
59 const char **arg;
60 int argc;
61 char **argp, **args;
62 struct elf_module *previous;
63 malloc_tag_t prev_mem_tag;
65 struct elf_module *module = module_alloc(name);
67 if (module == NULL)
68 return -1;
70 res = module_load(module);
71 if (res != 0) {
72 module_unload(module);
73 return res;
76 if (module->main_func == NULL) {
77 // We can't execute without a main function
78 module_unload(module);
79 return -1;
81 /*if (module->main_func != NULL) {
82 const char **last_arg = argv;
83 void *old_tag;
84 while (*last_arg != NULL)
85 last_arg++;
87 // Setup the memory allocation context
88 old_tag = __mem_get_tag_global();
89 __mem_set_tag_global(module);
91 // Execute the program
92 ret_val = (*(module->main_func))(last_arg - argv, argv);
94 // Clean up the allocation context
95 __free_tagged(module);
96 // Restore the allocation context
97 __mem_set_tag_global(old_tag);
98 } else {
99 // We can't execute without a main function
100 module_unload(module);
101 return -1;
103 // Set up the process context
104 previous = __syslinux_current;
105 prev_mem_tag = __mem_get_tag_global();
107 // Setup the new process context
108 __syslinux_current = module;
109 __mem_set_tag_global((malloc_tag_t)module);
111 // Generate a new process copy of argv (on the stack)
112 argc = 0;
113 for (arg = argv; *arg; arg++)
114 argc++;
116 args = alloca((argc+1) * sizeof(char *));
118 for (arg = argv, argp = args; *arg; arg++, argp++) {
119 size_t l = strlen(*arg)+1;
120 *argp = alloca(l);
121 memcpy(*argp, *arg, l);
124 *args = NULL;
126 // Execute the program
127 ret_val = setjmp(module->u.x.process_exit);
129 if (ret_val)
130 ret_val--; /* Valid range is 0-255 */
131 else if (!module->main_func)
132 ret_val = -1;
133 else
134 exit((module->main_func)(argc, args)); /* Actually run! */
136 // Clean up the allocation context
137 __free_tagged(module);
138 // Restore the allocation context
139 __mem_set_tag_global(prev_mem_tag);
140 // Restore the process context
141 __syslinux_current = previous;
143 res = module_unload(module);
145 if (res != 0) {
146 return res;
149 return ((unsigned int)ret_val & 0xFF);
152 int spawnl(const char *name, const char *arg, ...)
155 * NOTE: We assume the standard ABI specification for the i386
156 * architecture. This code may not work if used in other
157 * circumstances, including non-variadic functions, different
158 * architectures and calling conventions.
160 return spawnv(name, &arg);
162 #endif
164 struct elf_module *cur_module;
167 * Load a module and runs its start function.
169 * For library modules the start function is module->init_func and for
170 * executable modules its module->main_func.
172 * "name" is the name of the module to load.
174 * "argv" and "argc" are only passed to module->main_func, for library
175 * modules these arguments can be NULL and 0, respectively.
177 * "argv" is an array of arguments to pass to module->main_func.
178 * argv[0] must be a pointer to "name" and argv[argc] must be NULL.
180 * "argc" is the number of arguments in "argv".
182 int spawn_load(const char *name, int argc, char **argv)
184 int res, ret_val = 0;
185 struct elf_module *previous;
186 //malloc_tag_t prev_mem_tag;
187 struct elf_module *module = module_alloc(name);
188 struct elf_module *prev_module;
189 int type;
191 dprintf("enter: name = %s", name);
193 if (module == NULL)
194 return -1;
196 if (get_module_type(module) == EXEC_MODULE) {
197 if (!argc || !argv || strcmp(argv[0], name)) {
198 res = -1;
199 goto out;
203 if (!strcmp(cur_module->name, module->name)) {
204 dprintf("We is running this module %s already!", module->name);
207 * If we're already running the module and it's of
208 * type EXEC_MODULE, then just return. We don't reload
209 * the module because that might cause us to re-run
210 * the init functions, which will cause us to run the
211 * main function, which will take control of this
212 * process.
214 * This can happen if some other EXEC_MODULE is
215 * resolving a symbol that is exported by the current
216 * EXEC_MODULE.
218 if (get_module_type(module) == EXEC_MODULE)
219 return 0;
222 res = module_load(module);
223 if (res != 0)
224 goto out;
226 type = get_module_type(module);
227 prev_module = cur_module;
228 cur_module = module;
230 dprintf("type = %d, prev = %s, cur = %s",
231 type, prev_module->name, cur_module->name);
233 if(type==EXEC_MODULE)
235 previous = __syslinux_current;
236 //prev_mem_tag = __mem_get_tag_global();
238 // Setup the new process context
239 __syslinux_current = module;
240 //__mem_set_tag_global((malloc_tag_t)module);
242 // Execute the program
243 ret_val = setjmp(module->u.x.process_exit);
245 if (ret_val)
246 ret_val--; /* Valid range is 0-255 */
247 else if (!module->main_func)
248 ret_val = -1;
249 else
250 exit((module->main_func)(argc, argv)); /* Actually run! */
252 // Clean up the allocation context
253 //__free_tagged(module);
254 // Restore the allocation context
255 //__mem_set_tag_global(prev_mem_tag);
256 // Restore the process context
257 __syslinux_current = previous;
259 cur_module = prev_module;
260 res = module_unload(module);
262 if (res != 0)
263 goto out;
266 out:
267 if (res)
268 _module_unload(module);
269 return res;
272 void exec_term(void)
274 modules_term();