libc -- stdlib: Implement quick_exit and at_quick_exit from C11.
authorVenkatesh Srinivas <me@endeavour.zapto.org>
Fri, 24 Feb 2012 18:07:07 +0000 (10:07 -0800)
committerVenkatesh Srinivas <me@endeavour.zapto.org>
Fri, 24 Feb 2012 18:07:07 +0000 (10:07 -0800)
include/stdlib.h
lib/libc/stdlib/Makefile.inc
lib/libc/stdlib/quick_exit.c [new file with mode: 0644]

index ad34257..44b149a 100644 (file)
@@ -286,6 +286,12 @@ void        srandomdev(void);
 long long
         strtonum(const char *, long long, long long, const char **);
 
+/*
+ * C11 functions.
+ */
+int at_quick_exit(void (*func)(void));
+void quick_exit(int);
+
 /* Deprecated interfaces. */
 #if !defined(_KERNEL_VIRTUAL)
 __int64_t
index a8c8842..64d9a53 100644 (file)
@@ -1,6 +1,5 @@
 #      from @(#)Makefile.inc   8.3 (Berkeley) 2/4/95
 # $FreeBSD: src/lib/libc/stdlib/Makefile.inc,v 1.56 2008/10/17 08:30:20 netchild Exp $
-# $DragonFly: src/lib/libc/stdlib/Makefile.inc,v 1.24 2008/10/06 21:01:37 swildner Exp $
 
 # machine-independent stdlib sources
 .PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/stdlib ${.CURDIR}/../libc/stdlib
@@ -9,7 +8,8 @@ MISRCS+=a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \
        bsearch.c div.c exit.c getenv.c getopt.c getopt_long.c \
        getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c \
        insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \
-       merge.c ptsname.c qsort.c qsort_r.c radixsort.c rand.c random.c \
+       merge.c ptsname.c qsort.c qsort_r.c quick_exit.c \
+       radixsort.c rand.c random.c \
        reallocf.c realpath.c remque.c strfmon.c strtoimax.c \
        strtol.c strtoll.c strtonum.c strtoq.c strtoul.c strtoull.c \
        strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c
diff --git a/lib/libc/stdlib/quick_exit.c b/lib/libc/stdlib/quick_exit.c
new file mode 100644 (file)
index 0000000..ffd2f1d
--- /dev/null
@@ -0,0 +1,64 @@
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "libc_private.h"
+#include "spinlock.h"
+
+
+struct quick_exit_fn {
+       struct quick_exit_fn    *next;
+       void                    (*func)(void);
+};
+
+static struct quick_exit_fn *quick_exit_fns;
+static spinlock_t quick_exit_spinlock;
+
+/*
+ * at_quick_exit:
+ *
+ *     Register a function to be called at quick_exit.
+ */
+int
+at_quick_exit(void (*func)(void))
+{
+       struct quick_exit_fn *fn;
+
+       fn = malloc(sizeof(struct quick_exit_fn));
+       if (!fn)
+               return (-1);
+
+       fn->func = func;
+
+       if (__isthreaded)
+               _SPINLOCK(&quick_exit_spinlock);
+       
+       fn->next = quick_exit_fns;
+       quick_exit_fns = fn;
+
+       if (__isthreaded)
+               _SPINUNLOCK(&quick_exit_spinlock);
+
+       return (0);
+}
+
+/*
+ * quick_exit:
+ *
+ *     Abandon a process. Execute all quick_exit handlers.
+ */
+void
+quick_exit(int status)
+{
+       struct quick_exit_fn *fn;
+
+       if (__isthreaded)
+               _SPINLOCK(&quick_exit_spinlock);
+       for (fn = quick_exit_fns; fn != NULL; fn = fn->next) {
+               fn->func();
+       }
+       if (__isthreaded)
+               _SPINUNLOCK(&quick_exit_spinlock);
+
+       _exit(status);
+}