diff --git a/src/exit/atexit.c b/src/exit/atexit.c index 49c060e..ddfd90d 100644 --- a/src/exit/atexit.c +++ b/src/exit/atexit.c @@ -1,24 +1,12 @@ #include #include -#include #include "libc.h" -/* Ensure that at least 32 atexit handlers can be registered without malloc */ -#define COUNT 32 - -static struct fl -{ - struct fl *next; - void (*f[COUNT])(void); -} builtin, *head; +extern void *__dso_handle __attribute__((weak)); static int run_atexit_functions(void) { - int i; - for (; head; head=head->next) { - for (i=COUNT-1; i>=0 && !head->f[i]; i--); - for (; i>=0; i--) head->f[i](); - } + __cxa_finalize(NULL); return 0; } @@ -26,32 +14,8 @@ int (*const __funcs_on_exit)(void) = run_atexit_functions; int atexit(void (*func)(void)) { - static int lock; - int i; - /* Hook for atexit extensions */ if (libc.atexit) return libc.atexit(func); - LOCK(&lock); - - /* Defer initialization of head so it can be in BSS */ - if (!head) head = &builtin; - - /* If the current function list is full, add a new one */ - if (head->f[COUNT-1]) { - struct fl *new_fl = calloc(sizeof(struct fl), 1); - if (!new_fl) { - UNLOCK(&lock); - return -1; - } - new_fl->next = head; - head = new_fl; - } - - /* Append function to the list. */ - for (i=0; if[i]; i++); - head->f[i] = func; - - UNLOCK(&lock); - return 0; + return __cxa_atexit((void (*)(void *))func, NULL, &__dso_handle ? __dso_handle : NULL); } diff --git a/src/internal/libc.h b/src/internal/libc.h index 638ea52..902f5c7 100644 --- a/src/internal/libc.h +++ b/src/internal/libc.h @@ -58,4 +58,7 @@ extern char **__environ; #undef LFS64 #define LFS64(x) LFS64_2(x, x##64) +/* Required for C++ atexit handling, used by atexit */ +int __cxa_atexit(void (*)(void *), void *, void *); +void __cxa_finalize(void *); #endif