diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/exit/atexit.c | 33 | 
1 files changed, 26 insertions, 7 deletions
| diff --git a/src/exit/atexit.c b/src/exit/atexit.c index 6f00e374..c613d85b 100644 --- a/src/exit/atexit.c +++ b/src/exit/atexit.c @@ -1,5 +1,6 @@  #include <stddef.h>  #include <stdlib.h> +#include <stdint.h>  #include <limits.h>  #include "libc.h" @@ -9,26 +10,33 @@  static struct fl  {  	struct fl *next; -	void (*f[COUNT])(void); +	void (*f[COUNT])(void *); +	void *a[COUNT];  } builtin, *head; +static int lock; +  void __funcs_on_exit()  {  	int i; +	void (*func)(void *), *arg; +	LOCK(&lock);  	for (; head; head=head->next) {  		for (i=COUNT-1; i>=0 && !head->f[i]; i--); -		for (; i>=0; i--) head->f[i](); +		if (i<0) continue; +		func = head->f[i]; +		arg = head->a[i]; +		head->f[i] = 0; +		UNLOCK(&lock); +		func(arg); +		LOCK(&lock);  	}  } -int atexit(void (*func)(void)) +int __cxa_atexit(void (*func)(void *), void *arg, void *dso)  { -	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 */ @@ -48,7 +56,18 @@ int atexit(void (*func)(void))  	/* Append function to the list. */  	for (i=0; i<COUNT && head->f[i]; i++);  	head->f[i] = func; +	head->a[i] = arg;  	UNLOCK(&lock);  	return 0;  } + +static void call(void *p) +{ +	((void (*)(void))(uintptr_t)p)(); +} + +int atexit(void (*func)(void)) +{ +	return __cxa_atexit(call, (void *)(uintptr_t)func, 0); +} | 
