diff options
author | theraven <theraven@FreeBSD.org> | 2014-04-02 16:07:48 +0000 |
---|---|---|
committer | theraven <theraven@FreeBSD.org> | 2014-04-02 16:07:48 +0000 |
commit | 0127b103f27578fc7f9cc3389b299f221deb1d4c (patch) | |
tree | 6b79951e49825ea224053fd3b29a53481afa5e00 /lib/libc/stdlib/atexit.c | |
parent | 2b2f1d5e5ca561f2d22a5740eb522aba203a4bd9 (diff) | |
download | FreeBSD-src-0127b103f27578fc7f9cc3389b299f221deb1d4c.zip FreeBSD-src-0127b103f27578fc7f9cc3389b299f221deb1d4c.tar.gz |
Add support for some block functions that come from OS X. These are
intended to build with any C compiler.
Reviewed by: pfg
MFC after: 3 weeks
Diffstat (limited to 'lib/libc/stdlib/atexit.c')
-rw-r--r-- | lib/libc/stdlib/atexit.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/lib/libc/stdlib/atexit.c b/lib/libc/stdlib/atexit.c index 01d09fe..43b6aa1 100644 --- a/lib/libc/stdlib/atexit.c +++ b/lib/libc/stdlib/atexit.c @@ -37,6 +37,7 @@ static char sccsid[] = "@(#)atexit.c 8.2 (Berkeley) 7/3/94"; __FBSDID("$FreeBSD$"); #include "namespace.h" +#include <errno.h> #include <link.h> #include <stddef.h> #include <stdlib.h> @@ -44,9 +45,16 @@ __FBSDID("$FreeBSD$"); #include <pthread.h> #include "atexit.h" #include "un-namespace.h" +#include "block_abi.h" #include "libc_private.h" +/** + * The _Block_copy() function is provided by the block runtime. + */ +__attribute__((weak)) void* +_Block_copy(void*); + #define ATEXIT_FN_EMPTY 0 #define ATEXIT_FN_STD 1 #define ATEXIT_FN_CXA 2 @@ -125,7 +133,32 @@ atexit(void (*func)(void)) fn.fn_arg = NULL; fn.fn_dso = NULL; - error = atexit_register(&fn); + error = atexit_register(&fn); + return (error); +} + +/** + * Register a block to be performed at exit. + */ +int +atexit_b(DECLARE_BLOCK(void, func, void)) +{ + struct atexit_fn fn; + int error; + if (_Block_copy == 0) { + errno = ENOSYS; + return -1; + } + func = _Block_copy(func); + + // Blocks are not C++ destructors, but they have the same signature (a + // single void* parameter), so we can pretend that they are. + fn.fn_type = ATEXIT_FN_CXA; + fn.fn_ptr.cxa_func = (void(*)(void*))GET_BLOCK_FUNCTION(func); + fn.fn_arg = func; + fn.fn_dso = NULL; + + error = atexit_register(&fn); return (error); } @@ -144,7 +177,7 @@ __cxa_atexit(void (*func)(void *), void *arg, void *dso) fn.fn_arg = arg; fn.fn_dso = dso; - error = atexit_register(&fn); + error = atexit_register(&fn); return (error); } |