Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2004-09-09 23:46:54 +0400
committerJeff Johnston <jjohnstn@redhat.com>2004-09-09 23:46:54 +0400
commit0c8593cf11a16ca75c72977a6f5e3983896940c4 (patch)
tree8133764892ae91831d48980ef216fc4935e45b5f /newlib/libc/stdlib/__atexit.c
parent582dde69f31fb0dbe4beca5461b2b08924ae4e20 (diff)
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.c86
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;
+}