| @@ -54,6 +54,9 @@ static rt_context g_rtctxt; · 53 unmodified lines |
| 54 | static void set_exception_handler(void); | 54 | static void set_exception_handler(void); |
| 55 | static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap); | 55 | static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap); |
| 56 | static void rt_exit(int code); | 56 | static void rt_exit(int code); |
| | 57 | static void init_atexit(void); |
| | 58 | static void run_atexit(void); |
| | 59 | static int rt_atexit(void (*function)(void)); |
| 57 | #endif /* CONFIG_TCC_BACKTRACE */ | 60 | #endif /* CONFIG_TCC_BACKTRACE */ |
| 58 | | 61 | |
| 59 | /* defined when included from lib/bt-exe.c */ | 62 | /* defined when included from lib/bt-exe.c */ |
| @@ -169,6 +172,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 109 unmodified lines |
| 169 | if (s1->do_debug) | 172 | if (s1->do_debug) |
| 170 | tcc_add_symbol(s1, "exit", rt_exit); | 173 | tcc_add_symbol(s1, "exit", rt_exit); |
| 171 | #endif | 174 | #endif |
| | 175 | tcc_add_symbol(s1, "atexit", rt_atexit); |
| 172 | if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) | 176 | if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) |
| 173 | return -1; | 177 | return -1; |
| 174 | prog_main = (void*)get_sym_addr(s1, s1->runtime_main, 1, 1); | 178 | prog_main = (void*)get_sym_addr(s1, s1->runtime_main, 1, 1); |
| @@ -215,6 +219,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 40 unmodified lines |
| 215 | errno = 0; /* clean errno value */ | 219 | errno = 0; /* clean errno value */ |
| 216 | fflush(stdout); | 220 | fflush(stdout); |
| 217 | fflush(stderr); | 221 | fflush(stderr); |
| | 222 | init_atexit(); |
| 218 | /* These aren't C symbols, so don't need leading underscore handling. */ | 223 | /* These aren't C symbols, so don't need leading underscore handling. */ |
| 219 | run_cdtors(s1, "__init_array_start", "__init_array_end", argc, argv, envp); | 224 | run_cdtors(s1, "__init_array_start", "__init_array_end", argc, argv, envp); |
| 220 | #ifdef CONFIG_TCC_BACKTRACE | 225 | #ifdef CONFIG_TCC_BACKTRACE |
| @@ -224,6 +229,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 3 unmodified lines |
| 224 | ret = prog_main(argc, argv, envp); | 229 | ret = prog_main(argc, argv, envp); |
| 225 | } | 230 | } |
| 226 | run_cdtors(s1, "__fini_array_start", "__fini_array_end", 0, NULL, NULL); | 231 | run_cdtors(s1, "__fini_array_start", "__fini_array_end", 0, NULL, NULL); |
| | 232 | run_atexit(); |
| 227 | if ((s1->dflag & 16) && ret) | 233 | if ((s1->dflag & 16) && ret) |
| 228 | fprintf(s1->ppfp, "[returns %d]\n", ret), fflush(s1->ppfp); | 234 | fprintf(s1->ppfp, "[returns %d]\n", ret), fflush(s1->ppfp); |
| 229 | return ret; | 235 | return ret; |
| @@ -1022,6 +1028,29 @@ static void rt_exit(int code) · 792 unmodified lines |
| 1022 | exit(code); | 1028 | exit(code); |
| 1023 | } | 1029 | } |
| 1024 | | 1030 | |
| | 1031 | #define NR_AT_EXIT 32 |
| | 1032 | |
| | 1033 | static int nr_atexit = 0; |
| | 1034 | static void (*at_exitfunc[NR_AT_EXIT])(void); |
| | 1035 | |
| | 1036 | static void init_atexit(void) |
| | 1037 | { |
| | 1038 | nr_atexit = 0; |
| | 1039 | } |
| | 1040 | |
| | 1041 | static void run_atexit(void) |
| | 1042 | { |
| | 1043 | while (nr_atexit) |
| | 1044 | at_exitfunc[--nr_atexit](); |
| | 1045 | } |
| | 1046 | |
| | 1047 | static int rt_atexit(void (*function)(void)) |
| | 1048 | { |
| | 1049 | if (nr_atexit < NR_AT_EXIT) |
| | 1050 | at_exitfunc[nr_atexit++] = function; |
| | 1051 | return 1; |
| | 1052 | } |
| | 1053 | |
| 1025 | /* ------------------------------------------------------------- */ | 1054 | /* ------------------------------------------------------------- */ |
| 1026 | | 1055 | |
| 1027 | #ifndef _WIN32 | 1056 | #ifndef _WIN32 |