diff --git a/porting/liteos_a/user/src/exit/exit.c b/porting/liteos_a/user/src/exit/exit.c new file mode 100644 index 0000000000000000000000000000000000000000..5001bf12b86f5a29aa073f9f84bac7e1ed38b17f --- /dev/null +++ b/porting/liteos_a/user/src/exit/exit.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include "libc.h" + +static void dummy() +{ +} + +/* atexit.c and __stdio_exit.c override these. the latter is linked + * as a consequence of linking either __toread.c or __towrite.c. */ +weak_alias(dummy, __funcs_on_exit); +weak_alias(dummy, __stdio_exit); +weak_alias(dummy, _fini); + +extern weak hidden void (*const __fini_array_start)(void), (*const __fini_array_end)(void); + +static void libc_exit_fini(void) +{ + uintptr_t a = (uintptr_t)&__fini_array_end; + for (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)())) + (*(void (**)())(a-sizeof(void(*)())))(); + _fini(); +} + +weak_alias(libc_exit_fini, __libc_exit_fini); + +_Noreturn void exit(int code) +{ + sigset_t set; + if (a_cas(&libc.exit, 0, 1) != 0) { + return; + } + __block_app_sigs(&set); + __funcs_on_exit(); + __libc_exit_fini(); + __stdio_exit(); + _Exit(code); +} diff --git a/porting/liteos_a/user/src/internal/libc.h b/porting/liteos_a/user/src/internal/libc.h index da237ed147e38cea0ac2188e54d5df775fe71187..759f5b8a79d3afe3efc8f6915544dfb1883a439c 100644 --- a/porting/liteos_a/user/src/internal/libc.h +++ b/porting/liteos_a/user/src/internal/libc.h @@ -27,6 +27,7 @@ struct __libc { size_t tls_size, tls_align, tls_cnt; size_t page_size; struct __locale_struct global_locale; + int exit; }; #ifndef PAGE_SIZE diff --git a/porting/liteos_a/user/src/process/fork.c b/porting/liteos_a/user/src/process/fork.c index b5b8dca0abf6bd31541729086781d05692ade9d1..160ef5d2c19c3756b0e8dfe95fa1ee7d358e004e 100644 --- a/porting/liteos_a/user/src/process/fork.c +++ b/porting/liteos_a/user/src/process/fork.c @@ -30,6 +30,7 @@ pid_t fork(void) self->next = self->prev = self; __thread_list_lock = 0; libc.threads_minus_1 = 0; + libc.exit = 0; signal(SIGSYS, arm_do_signal); } __restore_sigs(&set); diff --git a/porting/liteos_a/user_debug/src/exit/exit.c b/porting/liteos_a/user_debug/src/exit/exit.c index 5d2d00a33b1b05a73f9bfdda58cf443d49f1645b..945da5206bf748e8837cd08009efbb09273c0d4d 100644 --- a/porting/liteos_a/user_debug/src/exit/exit.c +++ b/porting/liteos_a/user_debug/src/exit/exit.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include "libc.h" extern bool g_enable_check; @@ -32,6 +34,11 @@ weak_alias(libc_exit_fini, __libc_exit_fini); _Noreturn void exit(int code) { + sigset_t set; + if (a_cas(&libc.exit, 0, 1) != 0) { + return; + } + __block_app_sigs(&set); if (g_enable_check) { check_leak(); check_heap_integrity();