tccrun: review last changes
[tinycc.git] / lib / runmain.c
blob53cbe6de6dd0075518dd46b14efa1f1f10738134
1 /* ------------------------------------------------------------- */
2 /* support for tcc_run() */
4 #ifdef __leading_underscore
5 # define _(s) s
6 #else
7 # define _(s) _##s
8 #endif
10 #ifndef _WIN32
11 extern void (*_(_init_array_start)[]) (int argc, char **argv, char **envp);
12 extern void (*_(_init_array_end)[]) (int argc, char **argv, char **envp);
13 static void run_ctors(int argc, char **argv, char **env)
15 int i = 0;
16 while (&_(_init_array_start)[i] != _(_init_array_end))
17 (*_(_init_array_start)[i++])(argc, argv, env);
19 #endif
21 extern void (*_(_fini_array_start)[]) (void);
22 extern void (*_(_fini_array_end)[]) (void);
23 static void run_dtors(void)
25 int i = 0;
26 while (&_(_fini_array_end)[i] != _(_fini_array_start))
27 (*_(_fini_array_end)[--i])();
30 static void *rt_exitfunc[32];
31 static void *rt_exitarg[32];
32 static int __rt_nr_exit;
34 void __run_on_exit(int ret)
36 int n = __rt_nr_exit;
37 while (n)
38 --n, ((void(*)(int,void*))rt_exitfunc[n])(ret, rt_exitarg[n]);
41 int on_exit(void *function, void *arg)
43 int n = __rt_nr_exit;
44 if (n < 32) {
45 rt_exitfunc[n] = function;
46 rt_exitarg[n] = arg;
47 __rt_nr_exit = n + 1;
48 return 0;
50 return 1;
53 int atexit(void (*function)(void))
55 return on_exit(function, 0);
58 typedef struct rt_frame {
59 void *ip, *fp, *sp;
60 } rt_frame;
62 void __rt_exit(rt_frame *, int);
64 void exit(int code)
66 rt_frame f;
67 run_dtors();
68 __run_on_exit(code);
69 f.fp = 0;
70 f.ip = exit;
71 __rt_exit(&f, code);
74 #ifndef _WIN32
75 int main(int, char**, char**);
77 int _runmain(int argc, char **argv, char **envp)
79 int ret;
80 run_ctors(argc, argv, envp);
81 ret = main(argc, argv, envp);
82 run_dtors();
83 __run_on_exit(ret);
84 return ret;
86 #endif