diff options
author | Jakob Kaivo <jkk@ung.org> | 2024-01-31 01:11:36 -0500 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2024-01-31 01:11:36 -0500 |
commit | 5ca5b53beccb061a4390d23493e670d9f8b65cd7 (patch) | |
tree | 8ab5d59341e41c7eceb02b2cb2272adc37fd5ef8 | |
parent | d2b6b441366cb56785a92694e19a084642c1c99e (diff) |
fix up exit()/quick_exit() handlers
-rw-r--r-- | src/stdlib/at_quick_exit.c | 37 | ||||
-rw-r--r-- | src/stdlib/atexit.c | 1 | ||||
-rw-r--r-- | src/stdlib/exit.c | 9 | ||||
-rw-r--r-- | src/stdlib/quick_exit.c | 25 |
4 files changed, 37 insertions, 35 deletions
diff --git a/src/stdlib/at_quick_exit.c b/src/stdlib/at_quick_exit.c index e3ae86cc..6a6db796 100644 --- a/src/stdlib/at_quick_exit.c +++ b/src/stdlib/at_quick_exit.c @@ -8,32 +8,21 @@ int at_quick_exit(void (*func)(void)) { SIGNAL_SAFE(0); - (void)func; - - /* - if (__stdlib.at_quick_exit == NULL) { - __stdlib.at_quick_exit = calloc(1, - sizeof(*__stdlib.at_quick_exit)); - if (__stdlib.at_quick_exit == NULL) { - errno = ENOMEM; - return 1; + struct atexit *ae = &(__stdlib.at_quick_exit); + while (ae->nfns == sizeof(ae->fns) / sizeof(ae->fns[0])) { + if (ae->next == NULL) { + ae->next = calloc(1, sizeof(*ae->next)); + if (ae->next == NULL) { + #ifdef ENOMEM + errno = ENOMEM; + #endif + return 1; + } + ae->next->prev = ae; } - __stdlib.at_quick_exit->fn = func; - __stdlib.nat_quick_exit = 1; - return 0; - } - - __stdlib.at_quick_exit->next = calloc(1, - sizeof(*__stdlib.at_quick_exit->next)); - if (__stdlib.at_quick_exit->next == NULL) { - errno = ENOMEM; - return 1; + ae = ae->next; } - __stdlib.at_quick_exit->next->fn = func; - __stdlib.at_quick_exit->next->prev = __stdlib.at_quick_exit; - __stdlib.at_quick_exit = __stdlib.at_quick_exit->next; - __stdlib.nat_quick_exit++; - */ + ae->fns[ae->nfns++] = func; return 0; } diff --git a/src/stdlib/atexit.c b/src/stdlib/atexit.c index 4e20f993..d4b54c5f 100644 --- a/src/stdlib/atexit.c +++ b/src/stdlib/atexit.c @@ -24,6 +24,7 @@ int atexit(void (*func)(void)) ae = ae->next; } ae->fns[ae->nfns++] = func; + return 0; } diff --git a/src/stdlib/exit.c b/src/stdlib/exit.c index 12876050..cd3175d6 100644 --- a/src/stdlib/exit.c +++ b/src/stdlib/exit.c @@ -3,10 +3,13 @@ #include "_stdlib.h" #include "_syscall.h" +#if __STDC_VERSION__ < 199901L +#include "_Exit.c" +#endif + /** cause normal program termination **/ _Noreturn void exit(int status) { - long scno = __syscall_lookup(exit); struct atexit *ae = &(__stdlib.atexit); SIGNAL_SAFE(0); @@ -30,9 +33,7 @@ _Noreturn void exit(int status) fflush(NULL); - for (;;) { - __syscall(scno, status); - } + _Exit(status); } /*** diff --git a/src/stdlib/quick_exit.c b/src/stdlib/quick_exit.c index 06c69da8..3d754604 100644 --- a/src/stdlib/quick_exit.c +++ b/src/stdlib/quick_exit.c @@ -1,24 +1,35 @@ #include <stdlib.h> #include "_stdlib.h" +#include "_syscall.h" /** cause normal quick program termination **/ _Noreturn void quick_exit(int status) { SIGNAL_SAFE(1); + if (__stdlib.quick_exit_called) { + __stdlib.constraint_handler("Undefined behavior: quick_exit() called twice", NULL, 0); + } + if (__stdlib.exit_called) { + __stdlib.constraint_handler("Undefined behavior: quick_exit() called after exit", NULL, 0); + } + __stdlib.quick_exit_called = 1; + /* execute all at_quick_exit() registered functions in reverse order */ - /* - while (__stdlib.at_quick_exit) { - __stdlib.at_quick_exit->fn(); - __stdlib.at_quick_exit = __stdlib.at_quick_exit->prev; - } - */ + struct atexit *ae = &(__stdlib.at_quick_exit); + while (ae) { + int i = ae->nfns; + while (i > 0) { + ae->fns[--i](); + } + ae = ae->prev; + } fflush(NULL); // fclose(all the things); // remove(all the tmpfile()s); /* TODO */ - /* __syscall(exit, status); */ + _Exit(status); } |