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.
This commit is contained in:
Jeff Johnston 2004-09-09 19:46:54 +00:00
parent 582dde69f3
commit 0c8593cf11
13 changed files with 302 additions and 160 deletions

View File

@ -1,3 +1,26 @@
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.
2004-08-23 Jeff Johnston <jjohnstn@redhat.com>
* libc/include/sys/unistd.h (getpass): Change prototype to use

View File

@ -59,19 +59,24 @@ struct __tm
};
/*
* atexit() support. For _REENT_SMALL, we limit to 32 max.
* atexit() support.
*/
#define _ATEXIT_SIZE 32 /* must be at least 32 to guarantee ANSI conformance */
struct _on_exit_args {
void * _fnargs[_ATEXIT_SIZE]; /* fn args for on_exit */
void * _fnargs[_ATEXIT_SIZE]; /* user fn args */
void * _dso_handle[_ATEXIT_SIZE];
/* Bitmask is set if user function takes arguments. */
__ULong _fntypes; /* type of exit routine -
Must have at least _ATEXIT_SIZE bits */
Must have at least _ATEXIT_SIZE bits */
/* Bitmask is set if function was registered via __cxa_atexit. */
__ULong _is_cxa;
};
#ifdef _REENT_SMALL
struct _atexit {
struct _atexit *_next; /* next in list */
int _ind; /* next index in this table */
void (*_fns[_ATEXIT_SIZE])(void); /* the table itself */
struct _on_exit_args * _on_exit_args_ptr;
@ -80,6 +85,7 @@ struct _atexit {
struct _atexit {
struct _atexit *_next; /* next in list */
int _ind; /* next index in this table */
/* Some entries may already have been called, and will be NULL. */
void (*_fns[_ATEXIT_SIZE])(void); /* the table itself */
struct _on_exit_args _on_exit_args;
};
@ -371,7 +377,8 @@ struct _reent
void (**(_sig_func))(int);
/* atexit stuff */
struct _atexit _atexit;
struct _atexit *_atexit;
struct _atexit _atexit0;
struct _glue __sglue; /* root of glue chain */
__FILE *__sf; /* file descriptors */
@ -399,7 +406,8 @@ struct _reent
_NULL, \
_NULL, \
_NULL, \
{0, {_NULL}, _NULL}, \
_NULL, \
{_NULL, 0, {_NULL}, _NULL}, \
{_NULL, 0, _NULL}, \
_NULL, \
{_NULL, 0, 0, 0, 0, {_NULL, 0}, 0, _NULL}, \
@ -426,9 +434,11 @@ struct _reent
var->_localtime_buf = _NULL; \
var->_asctime_buf = _NULL; \
var->_sig_func = _NULL; \
var->_atexit._ind = 0; \
var->_atexit._fns[0] = _NULL; \
var->_atexit._on_exit_args = _NULL; \
var->_atexit = _NULL; \
var->_atexit0._next = _NULL; \
var->_atexit0._ind = 0; \
var->_atexit0._fns[0] = _NULL; \
var->_atexit0._on_exit_args_ptr = _NULL; \
var->__sglue._next = _NULL; \
var->__sglue._niobs = 0; \
var->__sglue._iobs = _NULL; \
@ -673,7 +683,7 @@ struct _reent
} \
}, \
_NULL, \
{_NULL, 0, {_NULL}, {{_NULL}, 0}}, \
{_NULL, 0, {_NULL}, {{_NULL}, {_NULL}, 0, 0}}, \
_NULL, \
{_NULL, 0, _NULL} \
}

View File

@ -81,8 +81,8 @@ _DEFUN (_reclaim_reent, (ptr),
_free_r (ptr, ptr->_localtime_buf);
if (ptr->_asctime_buf)
_free_r (ptr, ptr->_asctime_buf);
if (ptr->_atexit._on_exit_args_ptr)
_free_r (ptr, ptr->_atexit._on_exit_args_ptr);
if (ptr->_atexit->_on_exit_args_ptr)
_free_r (ptr, ptr->_atexit->_on_exit_args_ptr);
#else
/* atexit stuff */
if ((ptr->_atexit) && (ptr->_atexit != &ptr->_atexit0))

View File

@ -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 \

View File

@ -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 \

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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);
}

View File

@ -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));

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}