diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2004-09-09 19:46:54 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2004-09-09 19:46:54 +0000 |
commit | 0c8593cf11a16ca75c72977a6f5e3983896940c4 (patch) | |
tree | 8133764892ae91831d48980ef216fc4935e45b5f /newlib/libc/stdlib/__atexit.c | |
parent | 582dde69f31fb0dbe4beca5461b2b08924ae4e20 (diff) | |
download | cygnal-0c8593cf11a16ca75c72977a6f5e3983896940c4.tar.gz cygnal-0c8593cf11a16ca75c72977a6f5e3983896940c4.tar.bz2 cygnal-0c8593cf11a16ca75c72977a6f5e3983896940c4.zip |
2004-09-09 Paul Brook <paul@codesourcery.com>
* libc/include/sys/reent.h (struct _on_exit_args): Add _dso_handle
and _is_cxa.
(struct _atexit): Add _next when _REENT_SMALL.
(struct _reent): Add _atexit0 when _REENT_SMALL.
(_REENT_INIT_PTR): Adjust.
* libc/stdlib/Makefile.am (GENERAL_SOURCES): Add __atexit.c and
__call_exit.c.
(EXTENDED_SOURCES): Add cxa_atexit.c and cxa_finalize.c.
* libc/stdlib/Makefile.in: Regenerate.
* libc/stdlib/__atexit.c: New file.
* libc/stdlib/__call_atexit.c: New file.
* libc/stdlib/atexit.h: Remove old definitions. Add new.
* libc/stdlib/atexit.c (atexit): Use __register_exitproc.
* libc/stdlib/cxa_atexit.c: New file.
* libc/stdlib/cxa_finalize.c: New file.
* libc/stdlib/exit.c (exit): Use __call_exitprocs.
* libc/stdlib/on_exit.c (on_exit): Use __register_exitproc.
2004-09-09 Jeff Johnston <jjohnstn@redhat.com>
* libc/reent/reent.c [_REENT_SMALL]: Fix reference to
_on_exit_args_ptr.
Diffstat (limited to 'newlib/libc/stdlib/__atexit.c')
-rw-r--r-- | newlib/libc/stdlib/__atexit.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/newlib/libc/stdlib/__atexit.c b/newlib/libc/stdlib/__atexit.c new file mode 100644 index 000000000..0c843ade6 --- /dev/null +++ b/newlib/libc/stdlib/__atexit.c @@ -0,0 +1,86 @@ +/* + * Common routine to implement atexit-like functionality. + */ + +#include <stddef.h> +#include <stdlib.h> +#include <reent.h> +#include <sys/lock.h> +#include "atexit.h" + +/* + * Register a function to be performed at exit or on shared library unload. + */ + +int +_DEFUN (__register_exitproc, + (type, fn, arg, d), + int type _AND + void (*fn) (void) _AND + void *arg _AND + void *d) +{ + struct _on_exit_args * args; + register struct _atexit *p; + +#ifndef __SINGLE_THREAD__ + __LOCK_INIT(static, lock); + + __lock_acquire(lock); +#endif + + p = _GLOBAL_REENT->_atexit; + if (p == NULL) + _GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0; + if (p->_ind >= _ATEXIT_SIZE) + { + p = (struct _atexit *) malloc (sizeof *p); + if (p == NULL) + { +#ifndef __SINGLE_THREAD__ + __lock_release(lock); +#endif + return -1; + } + p->_ind = 0; + p->_next = _GLOBAL_REENT->_atexit; + _GLOBAL_REENT->_atexit = p; +#ifndef _REENT_SMALL + p->_on_exit_args._fntypes = 0; + p->_on_exit_args._is_cxa = 0; +#endif + } + + if (type != __et_atexit) + { +#ifdef _REENT_SMALL + args = p->_on_exit_args_ptr; + if (args == NULL) + { + args = malloc (sizeof * p->_on_exit_args_ptr); + if (args == NULL) + { +#ifndef __SINGLE_THREAD__ + __lock_release(lock); +#endif + return -1; + } + args->_fntypes = 0; + args->_is_cxa = 0; + p->_on_exit_args_ptr = args; + } +#else + args = &p->_on_exit_args; +#endif + args->_fnargs[p->_ind] = arg; + args->_dso_handle[p->_ind] = d; + args->_fntypes |= (1 << p->_ind); + if (type == __et_cxa) + args->_is_cxa |= (1 << p->_ind); + } + p->_fns[p->_ind++] = fn; +#ifndef __SINGLE_THREAD__ + __lock_release(lock); +#endif + return 0; +} |