Explorar el Código

support __cxa_atexit, and registering atexit functions from atexit handlers

mildly tested; may have bugs. the locking should be updated not to use
spinlocks but that's outside the scope of this one module.
Rich Felker hace 13 años
padre
commit
b7c683be35
Se han modificado 1 ficheros con 26 adiciones y 7 borrados
  1. 26 7
      src/exit/atexit.c

+ 26 - 7
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);
+}