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:
parent
582dde69f3
commit
0c8593cf11
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
/* 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} \
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue