summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cxa_atexit.c44
-rw-r--r--src/cxa_finalize.c8
2 files changed, 52 insertions, 0 deletions
diff --git a/src/cxa_atexit.c b/src/cxa_atexit.c
new file mode 100644
index 0000000..48d6d1d
--- /dev/null
+++ b/src/cxa_atexit.c
@@ -0,0 +1,44 @@
+#ifdef __sun__
+#include <pthread.h>
+#include <stdlib.h>
+
+static struct atexit_handler {
+ void (*f)(void *);
+ void *p;
+ void *d;
+ struct atexit_handler *next;
+} *head;
+
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+
+int __cxa_atexit( void (*f)(void *), void *p, void *d) {
+ pthread_mutex_lock(&lock);
+ struct atexit_handler *h = malloc(sizeof(*d));
+ if (!h) {
+ pthread_mutex_unlock(&lock);
+ return 1;
+ }
+ h->f = f;
+ h->p = p;
+ h->d = d;
+ h->next = head;
+ head = h;
+ pthread_mutex_unlock(&lock);
+ return 0;
+}
+
+void __cxa_finalize(void *d ) {
+ pthread_mutex_lock(&lock);
+ struct atexit_handler **last = &head;
+ for (struct atexit_handler *h = head ; h ; h = h->next) {
+ if ((h->d == d) || (d == 0)) {
+ *last = h->next;
+ h->f(h->p);
+ free(h);
+ } else {
+ last = &head->next;
+ }
+ }
+ pthread_mutex_unlock(&lock);
+}
+#endif
diff --git a/src/cxa_finalize.c b/src/cxa_finalize.c
new file mode 100644
index 0000000..c870ca8
--- /dev/null
+++ b/src/cxa_finalize.c
@@ -0,0 +1,8 @@
+void __cxa_finalize(void *d );
+
+extern void __dso_handle;
+
+__attribute((destructor))
+static void cleanup(void) {
+ __cxa_finalize(&__dso_handle);
+}