summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/stdlib.h14
-rw-r--r--lib/libc/stdlib/Makefile.inc8
-rw-r--r--lib/libc/stdlib/Symbol.map2
-rw-r--r--lib/libc/stdlib/at_quick_exit.358
-rw-r--r--lib/libc/stdlib/atexit.31
-rw-r--r--lib/libc/stdlib/exit.32
-rw-r--r--lib/libc/stdlib/quick_exit.355
-rw-r--r--lib/libc/stdlib/quick_exit.c81
-rw-r--r--sys/sys/cdefs.h11
9 files changed, 226 insertions, 6 deletions
diff --git a/include/stdlib.h b/include/stdlib.h
index 3c26dfb..d7e49d0 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -76,7 +76,7 @@ extern int __mb_cur_max;
extern int ___mb_cur_max(void);
#define MB_CUR_MAX (___mb_cur_max())
-void abort(void) __dead2;
+__noreturn void abort(void);
int abs(int) __pure2;
int atexit(void (*)(void));
double atof(const char *);
@@ -86,7 +86,7 @@ void *bsearch(const void *, const void *, size_t,
size_t, int (*)(const void *, const void *));
void *calloc(size_t, size_t) __malloc_like;
div_t div(int, int) __pure2;
-void exit(int) __dead2;
+__noreturn void exit(int);
void free(void *);
char *getenv(const char *);
long labs(long) __pure2;
@@ -145,10 +145,18 @@ unsigned long long
strtoull(const char * __restrict, char ** __restrict, int);
#endif /* __LONG_LONG_SUPPORTED */
-void _Exit(int) __dead2;
+__noreturn void _Exit(int);
#endif /* __ISO_C_VISIBLE >= 1999 */
/*
+ * If we're in a mode greater than C99, expose C1x functions.
+ */
+#if __ISO_C_VISIBLE > 1999
+__noreturn void quick_exit(int)
+int
+at_quick_exit(void (*func)(void));
+#endif /* __ISO_C_VISIBLE > 1999 */
+/*
* Extensions made by POSIX relative to C. We don't know yet which edition
* of POSIX made these extensions, so assume they've always been there until
* research can be done.
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index 3627294..7db0f60 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -8,8 +8,8 @@ MISRCS+=_Exit.c 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 malloc.c \
- merge.c ptsname.c qsort.c qsort_r.c radixsort.c rand.c random.c \
- reallocf.c realpath.c remque.c strfmon.c strtoimax.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 strtoq.c strtoul.c strtonum.c strtoull.c \
strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c
@@ -18,10 +18,12 @@ SYM_MAPS+= ${.CURDIR}/stdlib/Symbol.map
# machine-dependent stdlib sources
.sinclude "${.CURDIR}/${LIBC_ARCH}/stdlib/Makefile.inc"
-MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \
+MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 \
+ at_quick_exit.3 bsearch.3 \
div.3 exit.3 getenv.3 getopt.3 getopt_long.3 getsubopt.3 \
hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \
lsearch.3 malloc.3 memory.3 posix_memalign.3 ptsname.3 qsort.3 \
+ quick_exit.3 \
radixsort.3 rand.3 random.3 \
realpath.3 strfmon.3 strtod.3 strtol.3 strtonum.3 strtoul.3 system.3 \
tsearch.3
diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map
index c268ab9..897bccd 100644
--- a/lib/libc/stdlib/Symbol.map
+++ b/lib/libc/stdlib/Symbol.map
@@ -97,6 +97,8 @@ FBSD_1.3 {
atoi_l;
atol_l;
atoll_l;
+ at_quick_exit;
+ quick_exit;
strtod_l;
strtol_l;
strtoll_l;
diff --git a/lib/libc/stdlib/at_quick_exit.3 b/lib/libc/stdlib/at_quick_exit.3
new file mode 100644
index 0000000..241553f
--- /dev/null
+++ b/lib/libc/stdlib/at_quick_exit.3
@@ -0,0 +1,58 @@
+.\" Copyright (c) 2011 David Chisnall
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" /
+.Dd December 7, 2011o.Dt ATEXIT 3
+.Dt AT_QUICK_EXIT 3
+.Os
+.Sh NAME
+.Nm at_quick_exit
+.Nd Registers a cleanup function to run on quick exit.
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In stdlib.h
+.Ft int
+.Fn at_quick_exit "void (*func)(void)"
+.Sh DESCRIPTION
+The
+.Fn at_quick_exit
+function registers a cleanup function to be called when the program exits as a
+result of calling
+.Xr quick_exit 3 .
+The cleanup functions are called in the reverse order and will not be called if
+the program exits by calling
+.Xr exit 3 ,
+.Xr _Exit 3 ,
+or
+.Xr abort 3 .
+.El
+.Sh SEE ALSO
+.Xr exit 3 ,
+.Xr at_quick_exit 3
+.Sh STANDARDS
+The
+.Fn at_quick_exit
+function conforms to the C1x draft specification.
diff --git a/lib/libc/stdlib/atexit.3 b/lib/libc/stdlib/atexit.3
index 3c44b8d..3a514b9 100644
--- a/lib/libc/stdlib/atexit.3
+++ b/lib/libc/stdlib/atexit.3
@@ -79,6 +79,7 @@ No memory was available to add the function to the list.
The existing list of functions is unmodified.
.El
.Sh SEE ALSO
+.Xr at_quick_exit 3
.Xr exit 3
.Sh STANDARDS
The
diff --git a/lib/libc/stdlib/exit.3 b/lib/libc/stdlib/exit.3
index a864ccb..4547efe 100644
--- a/lib/libc/stdlib/exit.3
+++ b/lib/libc/stdlib/exit.3
@@ -118,7 +118,9 @@ never return.
.Xr _exit 2 ,
.Xr wait 2 ,
.Xr atexit 3 ,
+.Xr at_quick_exit 3 ,
.Xr intro 3 ,
+.Xr quick_exit 3 ,
.Xr sysexits 3 ,
.Xr tmpfile 3
.Sh STANDARDS
diff --git a/lib/libc/stdlib/quick_exit.3 b/lib/libc/stdlib/quick_exit.3
new file mode 100644
index 0000000..e29112f
--- /dev/null
+++ b/lib/libc/stdlib/quick_exit.3
@@ -0,0 +1,55 @@
+.\" Copyright (c) 2011 David Chisnall
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" /
+.Dd December 7, 2011o.Dt ATEXIT 3
+.Dt QUICK_EXIT 3
+.Os
+.Sh NAME
+.Nm quick_exit
+.Nd Exits a program quickly, running minimal cleanup
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In stdlib.h
+.Ft _Noreturn void
+.Fn quick_exit "void"
+.Sh DESCRIPTION
+The
+.Fn quick_exit
+function exits the program quickly calling any cleanup functions registered
+with
+.Xr at_quick_exit 3
+but not any C++ destructors or cleanup code registered with
+.Xr atexit 3 .
+.El
+.Sh SEE ALSO
+.Xr exit 3 ,
+.Xr at_quick_exit 3
+.Sh STANDARDS
+The
+.Fn quick_exit
+function conforms to the C1x draft specification.
+
diff --git a/lib/libc/stdlib/quick_exit.c b/lib/libc/stdlib/quick_exit.c
new file mode 100644
index 0000000..11e22da
--- /dev/null
+++ b/lib/libc/stdlib/quick_exit.c
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 2011 David Chisnall
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdlib.h>
+#include <pthread.h>
+
+/**
+ * Linked list of quick exit handlers. This is simpler than the atexit()
+ * version, because it is not required to support C++ destructors or
+ * DSO-specific cleanups.
+ */
+struct quick_exit_handler {
+ struct quick_exit_handler *next;
+ void (*cleanup)(void);
+};
+
+__attribute((weak))
+void _ZSt9terminatev(void);
+
+/**
+ * Lock protecting the handlers list.
+ */
+static pthread_mutex_t atexit_mutex = PTHREAD_MUTEX_INITIALIZER;
+/**
+ * Stack of cleanup handlers. These will be invoked in reverse order when
+ */
+static struct quick_exit_handler *handlers;
+
+int
+at_quick_exit(void (*func)(void))
+{
+ struct quick_exit_handler *h = malloc(sizeof(struct quick_exit_handler));
+
+ if (0 == h) {
+ return 1;
+ }
+ h->cleanup = func;
+ pthread_mutex_lock(&atexit_mutex);
+ h->next = handlers;
+ handlers = h;
+ pthread_mutex_unlock(&atexit_mutex);
+ return 0;
+}
+
+void quick_exit(int status)
+{
+ /*
+ * XXX: The C++ spec requires us to call std::terminate if there is an
+ * exception here.
+ */
+ for (struct quick_exit_handler *h = handlers ; NULL != h ; h = h->next)
+ {
+ h->cleanup();
+ }
+ _Exit(status);
+}
diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h
index 495daf2..ca485b3 100644
--- a/sys/sys/cdefs.h
+++ b/sys/sys/cdefs.h
@@ -218,6 +218,17 @@
#endif
#endif
+
+#if defined(__cplusplus) && __cplusplus >= 201103L
+#define __noreturn [[noreturn]]
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ > 201000L
+#define __noreturn _Noreturn
+#elif defined(__GNUC__)
+#define __noreturn __attribute__((__noreturn__))
+#else
+#define __noreturn
+#endif
+
#if __GNUC_PREREQ__(2, 96)
#define __malloc_like __attribute__((__malloc__))
#define __pure __attribute__((__pure__))
OpenPOWER on IntegriCloud