From 0b44a0315b47dd8eced9f3b7f31580cf14bbfc01 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 12 Feb 2011 00:22:29 -0500 Subject: initial check-in, version 0.5.0 --- src/exit/atexit.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/exit/atexit.c (limited to 'src/exit/atexit.c') diff --git a/src/exit/atexit.c b/src/exit/atexit.c new file mode 100644 index 00000000..49c060e6 --- /dev/null +++ b/src/exit/atexit.c @@ -0,0 +1,57 @@ +#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; + +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](); + } + return 0; +} + +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; +} -- cgit 1.4.1