summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2024-01-31 01:11:36 -0500
committerJakob Kaivo <jkk@ung.org>2024-01-31 01:11:36 -0500
commit5ca5b53beccb061a4390d23493e670d9f8b65cd7 (patch)
tree8ab5d59341e41c7eceb02b2cb2272adc37fd5ef8
parentd2b6b441366cb56785a92694e19a084642c1c99e (diff)
fix up exit()/quick_exit() handlers
-rw-r--r--src/stdlib/at_quick_exit.c37
-rw-r--r--src/stdlib/atexit.c1
-rw-r--r--src/stdlib/exit.c9
-rw-r--r--src/stdlib/quick_exit.c25
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);
}