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
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')
-rw-r--r--newlib/libc/stdlib/Makefile.am4
-rw-r--r--newlib/libc/stdlib/Makefile.in50
-rw-r--r--newlib/libc/stdlib/__atexit.c86
-rw-r--r--newlib/libc/stdlib/__call_atexit.c83
-rw-r--r--newlib/libc/stdlib/atexit.c46
-rw-r--r--newlib/libc/stdlib/atexit.h17
-rw-r--r--newlib/libc/stdlib/cxa_atexit.c23
-rw-r--r--newlib/libc/stdlib/cxa_finalize.c20
-rw-r--r--newlib/libc/stdlib/exit.c39
-rw-r--r--newlib/libc/stdlib/on_exit.c39
10 files changed, 258 insertions, 149 deletions
diff --git a/newlib/libc/stdlib/Makefile.am b/newlib/libc/stdlib/Makefile.am
index 471d17d00..36e61074f 100644
--- a/newlib/libc/stdlib/Makefile.am
+++ b/newlib/libc/stdlib/Makefile.am
@@ -6,6 +6,8 @@ INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
GENERAL_SOURCES = \
__adjust.c \
+ __atexit.c \
+ __call_atexit.c \
__exp10.c \
__ten_mu.c \
_Exit.c \
@@ -52,6 +54,8 @@ GENERAL_SOURCES = \
wctomb_r.c
EXTENDED_SOURCES = \
+ cxa_atexit.c \
+ cxa_finalize.c \
drand48.c \
ecvtbuf.c \
efgcvt.c \
diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in
index d6c264440..46d96b859 100644
--- a/newlib/libc/stdlib/Makefile.in
+++ b/newlib/libc/stdlib/Makefile.in
@@ -110,10 +110,10 @@ AUTOMAKE_OPTIONS = cygnus
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
-GENERAL_SOURCES = __adjust.c __exp10.c __ten_mu.c _Exit.c abort.c abs.c assert.c atexit.c atof.c atoff.c atoi.c atol.c calloc.c div.c dtoa.c dtoastub.c environ.c envlock.c eprintf.c exit.c getenv.c getenv_r.c labs.c ldiv.c ldtoa.c malloc.c mblen.c mblen_r.c mbstowcs.c mbstowcs_r.c mbtowc.c mbtowc_r.c mlock.c mprec.c mstats.c rand.c rand_r.c realloc.c strtod.c strtol.c strtoul.c wcstombs.c wcstombs_r.c wctomb.c wctomb_r.c
+GENERAL_SOURCES = __adjust.c __atexit.c __call_atexit.c __exp10.c __ten_mu.c _Exit.c abort.c abs.c assert.c atexit.c atof.c atoff.c atoi.c atol.c calloc.c div.c dtoa.c dtoastub.c environ.c envlock.c eprintf.c exit.c getenv.c getenv_r.c labs.c ldiv.c ldtoa.c malloc.c mblen.c mblen_r.c mbstowcs.c mbstowcs_r.c mbtowc.c mbtowc_r.c mlock.c mprec.c mstats.c rand.c rand_r.c realloc.c strtod.c strtol.c strtoul.c wcstombs.c wcstombs_r.c wctomb.c wctomb_r.c
-EXTENDED_SOURCES = drand48.c ecvtbuf.c efgcvt.c erand48.c jrand48.c lcong48.c lrand48.c mrand48.c msize.c mtrim.c nrand48.c rand48.c seed48.c srand48.c strtoll.c strtoll_r.c strtoull.c strtoull_r.c atoll.c llabs.c lldiv.c
+EXTENDED_SOURCES = cxa_atexit.c cxa_finalize.c drand48.c ecvtbuf.c efgcvt.c erand48.c jrand48.c lcong48.c lrand48.c mrand48.c msize.c mtrim.c nrand48.c rand48.c seed48.c srand48.c strtoll.c strtoll_r.c strtoull.c strtoull_r.c atoll.c llabs.c lldiv.c
ELIX_2_OBJS = a64l.$(oext) btowc.$(oext) getopt.$(oext) getsubopt.$(oext) l64a.$(oext) malign.$(oext) malignr.$(oext) malloptr.$(oext) mbrlen.$(oext) mbrtowc.$(oext) mbsinit.$(oext) mbsrtowcs.$(oext) on_exit.$(oext) pvallocr.$(oext) valloc.$(oext) vallocr.$(oext) wcrtomb.$(oext) wcsrtombs.$(oext) wctob.$(oext)
@@ -168,23 +168,26 @@ LIBRARIES = $(noinst_LIBRARIES)
DEFS = @DEFS@ -I. -I$(srcdir)
CPPFLAGS = @CPPFLAGS@
LIBS = @LIBS@
-@USE_LIBTOOL_FALSE@lib_a_OBJECTS = __adjust.$(OBJEXT) __exp10.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@__ten_mu.$(OBJEXT) _Exit.$(OBJEXT) abort.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@abs.$(OBJEXT) assert.$(OBJEXT) atexit.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@atof.$(OBJEXT) atoff.$(OBJEXT) atoi.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@atol.$(OBJEXT) calloc.$(OBJEXT) div.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@dtoa.$(OBJEXT) dtoastub.$(OBJEXT) environ.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@envlock.$(OBJEXT) eprintf.$(OBJEXT) exit.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@getenv.$(OBJEXT) getenv_r.$(OBJEXT) labs.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@ldiv.$(OBJEXT) ldtoa.$(OBJEXT) malloc.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@mblen.$(OBJEXT) mblen_r.$(OBJEXT) mbstowcs.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@lib_a_OBJECTS = __adjust.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@__atexit.$(OBJEXT) __call_atexit.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@__exp10.$(OBJEXT) __ten_mu.$(OBJEXT) _Exit.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@abort.$(OBJEXT) abs.$(OBJEXT) assert.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@atexit.$(OBJEXT) atof.$(OBJEXT) atoff.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@atoi.$(OBJEXT) atol.$(OBJEXT) calloc.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@div.$(OBJEXT) dtoa.$(OBJEXT) dtoastub.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@environ.$(OBJEXT) envlock.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@eprintf.$(OBJEXT) exit.$(OBJEXT) getenv.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@getenv_r.$(OBJEXT) labs.$(OBJEXT) ldiv.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@ldtoa.$(OBJEXT) malloc.$(OBJEXT) mblen.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@mblen_r.$(OBJEXT) mbstowcs.$(OBJEXT) \
@USE_LIBTOOL_FALSE@mbstowcs_r.$(OBJEXT) mbtowc.$(OBJEXT) \
@USE_LIBTOOL_FALSE@mbtowc_r.$(OBJEXT) mlock.$(OBJEXT) mprec.$(OBJEXT) \
@USE_LIBTOOL_FALSE@mstats.$(OBJEXT) rand.$(OBJEXT) rand_r.$(OBJEXT) \
@USE_LIBTOOL_FALSE@realloc.$(OBJEXT) strtod.$(OBJEXT) strtol.$(OBJEXT) \
@USE_LIBTOOL_FALSE@strtoul.$(OBJEXT) wcstombs.$(OBJEXT) \
@USE_LIBTOOL_FALSE@wcstombs_r.$(OBJEXT) wctomb.$(OBJEXT) \
-@USE_LIBTOOL_FALSE@wctomb_r.$(OBJEXT) drand48.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@wctomb_r.$(OBJEXT) cxa_atexit.$(OBJEXT) \
+@USE_LIBTOOL_FALSE@cxa_finalize.$(OBJEXT) drand48.$(OBJEXT) \
@USE_LIBTOOL_FALSE@ecvtbuf.$(OBJEXT) efgcvt.$(OBJEXT) erand48.$(OBJEXT) \
@USE_LIBTOOL_FALSE@jrand48.$(OBJEXT) lcong48.$(OBJEXT) \
@USE_LIBTOOL_FALSE@lrand48.$(OBJEXT) mrand48.$(OBJEXT) msize.$(OBJEXT) \
@@ -195,16 +198,17 @@ LIBS = @LIBS@
@USE_LIBTOOL_FALSE@lldiv.$(OBJEXT)
LTLIBRARIES = $(noinst_LTLIBRARIES)
-@USE_LIBTOOL_TRUE@libstdlib_la_OBJECTS = __adjust.lo __exp10.lo \
-@USE_LIBTOOL_TRUE@__ten_mu.lo _Exit.lo abort.lo abs.lo assert.lo \
-@USE_LIBTOOL_TRUE@atexit.lo atof.lo atoff.lo atoi.lo atol.lo calloc.lo \
-@USE_LIBTOOL_TRUE@div.lo dtoa.lo dtoastub.lo environ.lo envlock.lo \
-@USE_LIBTOOL_TRUE@eprintf.lo exit.lo getenv.lo getenv_r.lo labs.lo \
-@USE_LIBTOOL_TRUE@ldiv.lo ldtoa.lo malloc.lo mblen.lo mblen_r.lo \
-@USE_LIBTOOL_TRUE@mbstowcs.lo mbstowcs_r.lo mbtowc.lo mbtowc_r.lo \
-@USE_LIBTOOL_TRUE@mlock.lo mprec.lo mstats.lo rand.lo rand_r.lo \
-@USE_LIBTOOL_TRUE@realloc.lo strtod.lo strtol.lo strtoul.lo wcstombs.lo \
-@USE_LIBTOOL_TRUE@wcstombs_r.lo wctomb.lo wctomb_r.lo drand48.lo \
+@USE_LIBTOOL_TRUE@libstdlib_la_OBJECTS = __adjust.lo __atexit.lo \
+@USE_LIBTOOL_TRUE@__call_atexit.lo __exp10.lo __ten_mu.lo _Exit.lo \
+@USE_LIBTOOL_TRUE@abort.lo abs.lo assert.lo atexit.lo atof.lo atoff.lo \
+@USE_LIBTOOL_TRUE@atoi.lo atol.lo calloc.lo div.lo dtoa.lo dtoastub.lo \
+@USE_LIBTOOL_TRUE@environ.lo envlock.lo eprintf.lo exit.lo getenv.lo \
+@USE_LIBTOOL_TRUE@getenv_r.lo labs.lo ldiv.lo ldtoa.lo malloc.lo \
+@USE_LIBTOOL_TRUE@mblen.lo mblen_r.lo mbstowcs.lo mbstowcs_r.lo \
+@USE_LIBTOOL_TRUE@mbtowc.lo mbtowc_r.lo mlock.lo mprec.lo mstats.lo \
+@USE_LIBTOOL_TRUE@rand.lo rand_r.lo realloc.lo strtod.lo strtol.lo \
+@USE_LIBTOOL_TRUE@strtoul.lo wcstombs.lo wcstombs_r.lo wctomb.lo \
+@USE_LIBTOOL_TRUE@wctomb_r.lo cxa_atexit.lo cxa_finalize.lo drand48.lo \
@USE_LIBTOOL_TRUE@ecvtbuf.lo efgcvt.lo erand48.lo jrand48.lo lcong48.lo \
@USE_LIBTOOL_TRUE@lrand48.lo mrand48.lo msize.lo mtrim.lo nrand48.lo \
@USE_LIBTOOL_TRUE@rand48.lo seed48.lo srand48.lo strtoll.lo \
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;
+}
diff --git a/newlib/libc/stdlib/__call_atexit.c b/newlib/libc/stdlib/__call_atexit.c
new file mode 100644
index 000000000..cea569ff4
--- /dev/null
+++ b/newlib/libc/stdlib/__call_atexit.c
@@ -0,0 +1,83 @@
+/*
+ * COmmon routine to call call registered atexit-like routines.
+ */
+
+
+#include <stdlib.h>
+#include <reent.h>
+#include "atexit.h"
+
+/*
+ * Call registered exit handlers. If D is null then all handlers are called,
+ * otherwise only the handlers from that DSO are called.
+ */
+
+void
+_DEFUN (__call_exitprocs, (code, d),
+ int code _AND _PTR d)
+{
+ register struct _atexit *p;
+ struct _atexit **lastp;
+ register struct _on_exit_args * args;
+ register int n;
+ int i;
+ void (*fn) (void);
+
+ p = _GLOBAL_REENT->_atexit;
+ lastp = &_GLOBAL_REENT->_atexit;
+ while (p)
+ {
+#ifdef _REENT_SMALL
+ args = p->_on_exit_args_ptr;
+#else
+ args = &p->_on_exit_args;
+#endif
+ for (n = p->_ind - 1; n >= 0; n--)
+ {
+ i = 1 << n;
+
+ /* Skip functions not from this dso. */
+ if (d && (!args || args->_dso_handle[n] != d))
+ continue;
+
+ /* Remove the function now to protect against the
+ function calling exit recursively. */
+ fn = p->_fns[n];
+ if (n == p->_ind - 1)
+ p->_ind--;
+ else
+ p->_fns[n] = NULL;
+
+ /* Skip functions that have already been called. */
+ if (!fn)
+ continue;
+
+ /* Call the function. */
+ if (!args || (args->_fntypes & i) == 0)
+ fn ();
+ else if ((args->_is_cxa & i) == 0)
+ (*((void (*)(int, _PTR)) fn))(code, args->_fnargs[n]);
+ else
+ (*((void (*)(_PTR)) fn))(args->_fnargs[n]);
+ }
+
+ /* Move to the next block. Free empty blocks except the last one,
+ which is part of _GLOBAL_REENT. */
+ if (p->_ind == 0 && p->_next)
+ {
+ /* Remove empty block from the list. */
+ *lastp = p->_next;
+#ifdef _REENT_SMALL
+ if (args)
+ free (args);
+#endif
+ free (p);
+ p = *lastp;
+ }
+ else
+ {
+ lastp = &p->_next;
+ p = p->_next;
+ }
+ }
+}
diff --git a/newlib/libc/stdlib/atexit.c b/newlib/libc/stdlib/atexit.c
index 3a9cdc6a3..21ffd6e7b 100644
--- a/newlib/libc/stdlib/atexit.c
+++ b/newlib/libc/stdlib/atexit.c
@@ -50,10 +50,8 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
-#include <stddef.h>
#include <stdlib.h>
-#include <reent.h>
-#include <sys/lock.h>
+#include "atexit.h"
/*
* Register a function to be performed at exit.
@@ -64,45 +62,5 @@ _DEFUN (atexit,
(fn),
_VOID _EXFUN ((*fn), (_VOID)))
{
- register struct _atexit *p;
-
-#ifndef __SINGLE_THREAD__
- __LOCK_INIT(static, lock);
-
- __lock_acquire(lock);
-#endif
-
- /* _REENT_SMALL atexit() doesn't allow more than the required 32 entries. */
-#ifndef _REENT_SMALL
- if ((p = _GLOBAL_REENT->_atexit) == NULL)
- _GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0;
- if (p->_ind >= _ATEXIT_SIZE)
- {
- if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
- {
-#ifndef __SINGLE_THREAD__
- __lock_release(lock);
-#endif
- return -1;
- }
- p->_ind = 0;
- p->_on_exit_args._fntypes = 0;
- p->_next = _GLOBAL_REENT->_atexit;
- _GLOBAL_REENT->_atexit = p;
- }
-#else
- p = &_GLOBAL_REENT->_atexit;
- if (p->_ind >= _ATEXIT_SIZE)
- {
-#ifndef __SINGLE_THREAD__
- __lock_release(lock);
-#endif
- return -1;
- }
-#endif
- p->_fns[p->_ind++] = fn;
-#ifndef __SINGLE_THREAD__
- __lock_release(lock);
-#endif
- return 0;
+ return __register_exitproc (__et_atexit, fn, NULL, NULL);
}
diff --git a/newlib/libc/stdlib/atexit.h b/newlib/libc/stdlib/atexit.h
index 44a928126..e37a146a0 100644
--- a/newlib/libc/stdlib/atexit.h
+++ b/newlib/libc/stdlib/atexit.h
@@ -1,13 +1,14 @@
/*
- * %G% (UofMD) %D%
+ * Common definitions for atexit-like routines
*/
-#define ATEXIT_SIZE 32 /* must be at least 32 to guarantee ANSI conformance */
-
-struct atexit {
- struct atexit *next; /* next in list */
- int ind; /* next index in this table */
- void (*fns[ATEXIT_SIZE])(); /* the table itself */
+enum __atexit_types
+{
+ __et_atexit,
+ __et_onexit,
+ __et_cxa
};
-struct atexit *__atexit; /* points to head of LIFO stack */
+void __call_exitprocs _PARAMS ((int, _PTR));
+int __register_exitproc _PARAMS ((int, void (*fn) (void), _PTR, _PTR));
+
diff --git a/newlib/libc/stdlib/cxa_atexit.c b/newlib/libc/stdlib/cxa_atexit.c
new file mode 100644
index 000000000..8c39236de
--- /dev/null
+++ b/newlib/libc/stdlib/cxa_atexit.c
@@ -0,0 +1,23 @@
+/*
+ * Implementation of __cxa_atexit.
+ */
+
+#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 DSO unload.
+ */
+
+int
+_DEFUN (__cxa_atexit,
+ (fn, arg, d),
+ void (*fn) (void *) _AND
+ void *arg _AND
+ void *d)
+{
+ return __register_exitproc (__et_cxa, (void (*)(void)) fn, arg, d);
+}
diff --git a/newlib/libc/stdlib/cxa_finalize.c b/newlib/libc/stdlib/cxa_finalize.c
new file mode 100644
index 000000000..17d0526a7
--- /dev/null
+++ b/newlib/libc/stdlib/cxa_finalize.c
@@ -0,0 +1,20 @@
+/*
+ * Implementation if __cxa_finalize.
+ */
+
+
+#include <stdlib.h>
+#include <reent.h>
+#include "atexit.h"
+
+/*
+ * Call registered exit handlers. If D is null then all handlers are called,
+ * otherwise only the handlers from that DSO are called.
+ */
+
+void
+_DEFUN (__cxa_finalize, (d),
+ void * d)
+{
+ __call_exitprocs (0, d);
+}
diff --git a/newlib/libc/stdlib/exit.c b/newlib/libc/stdlib/exit.c
index be96488c8..b5ef05f5b 100644
--- a/newlib/libc/stdlib/exit.c
+++ b/newlib/libc/stdlib/exit.c
@@ -48,6 +48,7 @@ Supporting OS subroutines required: <<_exit>>.
#include <stdlib.h>
#include <unistd.h> /* for _exit() declaration */
#include <reent.h>
+#include "atexit.h"
#ifndef _REENT_ONLY
@@ -59,43 +60,7 @@ void
_DEFUN (exit, (code),
int code)
{
- register struct _atexit *p;
- register struct _on_exit_args * args;
- register int n;
- int i;
-
-#ifdef _REENT_SMALL
- p = &_GLOBAL_REENT->_atexit;
- args = p->_on_exit_args_ptr;
-
- if (args == NULL)
- {
- for (n = p->_ind; n--;)
- p->_fns[n] ();
- }
- else
- {
- for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1)
- if (args->_fntypes & i)
- (*((void (*)(int, void *)) p->_fns[n]))(code, args->_fnargs[n]);
- else
- p->_fns[n] ();
- }
-#else
- p = _GLOBAL_REENT->_atexit;
- while (p)
- {
- args = & p->_on_exit_args;
-
- for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1)
- if (args->_fntypes & i)
- (*((void (*)(int, void *)) p->_fns[n]))(code, args->_fnargs[n]);
- else
- p->_fns[n] ();
-
- p = p->_next;
- }
-#endif
+ __call_exitprocs (code, NULL);
if (_GLOBAL_REENT->__cleanup)
(*_GLOBAL_REENT->__cleanup) (_GLOBAL_REENT);
diff --git a/newlib/libc/stdlib/on_exit.c b/newlib/libc/stdlib/on_exit.c
index f3383501f..3ac7f998b 100644
--- a/newlib/libc/stdlib/on_exit.c
+++ b/newlib/libc/stdlib/on_exit.c
@@ -56,7 +56,7 @@ Supporting OS subroutines required: None
#include <stddef.h>
#include <stdlib.h>
-#include <reent.h>
+#include "atexit.h"
/*
* Register a function to be performed at exit.
@@ -68,40 +68,5 @@ _DEFUN (on_exit,
_VOID _EXFUN ((*fn), (int, _PTR)) _AND
_PTR arg)
{
- struct _on_exit_args * args;
- register struct _atexit *p;
- void (*x)(void) = (void (*)(void))fn;
-
-/* _REENT_SMALL on_exit() doesn't allow more than the required 32 entries. */
-#ifdef _REENT_SMALL
- p = &_GLOBAL_REENT->_atexit;
- if (p->_ind >= _ATEXIT_SIZE)
- return -1;
- args = p->_on_exit_args_ptr;
- if (args == NULL)
- {
- args = malloc (sizeof * p->_on_exit_args_ptr);
- if (args == NULL)
- return -1;
- args->_fntypes = 0;
- p->_on_exit_args_ptr = args;
- }
-#else
- if ((p = _GLOBAL_REENT->_atexit) == NULL)
- _GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0;
- if (p->_ind >= _ATEXIT_SIZE)
- {
- if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
- return -1;
- p->_ind = 0;
- p->_on_exit_args._fntypes = 0;
- p->_next = _GLOBAL_REENT->_atexit;
- _GLOBAL_REENT->_atexit = p;
- }
- args = & p->_on_exit_args;
-#endif
- args->_fntypes |= (1 << p->_ind);
- args->_fnargs[p->_ind] = arg;
- p->_fns[p->_ind++] = x;
- return 0;
+ return __register_exitproc (__et_onexit, (void (*)(void)) fn, arg, NULL);
}