From ded93cd9e74a8cb2766f3a3f2ecaab59747c59e4 Mon Sep 17 00:00:00 2001 From: theraven Date: Wed, 7 Dec 2011 15:25:48 +0000 Subject: Implement quick_exit() / at_quick_exit() from C++11 / C1x. Also add a __noreturn macro and modify the other exiting functions to use it. The __noreturn macro, unlike __dead2, must be used BEFORE the function. This is in line with the C and C++ specifications that place _Noreturn (c1x) and [[noreturn]] (C++11) in front of the functions. As with __dead2, this macro falls back to using the GCC attribute. Unfortunately, clang currently sets the same value for the C version macro in C99 and C1x modes, so these functions are hidden by default. At some point before 10.0, I need to go through the headers and clean up the C1x / C++11 visibility. Reviewed by: brooks (mentor) --- lib/libc/stdlib/Makefile.inc | 8 ++-- lib/libc/stdlib/Symbol.map | 2 + lib/libc/stdlib/at_quick_exit.3 | 58 +++++++++++++++++++++++++++++ lib/libc/stdlib/atexit.3 | 1 + lib/libc/stdlib/exit.3 | 2 + lib/libc/stdlib/quick_exit.3 | 55 ++++++++++++++++++++++++++++ lib/libc/stdlib/quick_exit.c | 81 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 lib/libc/stdlib/at_quick_exit.3 create mode 100644 lib/libc/stdlib/quick_exit.3 create mode 100644 lib/libc/stdlib/quick_exit.c (limited to 'lib') 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 +#include + +/** + * 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); +} -- cgit v1.1