2002-05-15 Jeff Johnston <jjohnstn@redhat.com>
* libc/include/stdlib.h: Add on_exit prototype. * libc/include/sys/reent.h (struct _atexit): Add argument array and bits to track type of exit routine to support both on_exit and atexit. (_REENT_INIT_PTR): Add missing fields that won't be zeroed out by default and change the setting of the atexit structure. (_REENT_INIT)[!_REENT_SMALL]: Remove extraneous end brace. * libc/stdlib/on_exit.c: New file. * libc/stdlib/Makefile.am: Add support for on_exit. * libc/stdlib/Makefile.in: Regenerated. * libc/stdlib/atexit.c: Change to initialize types field. * libc/stdlib/exit.c: Change to look at types field for each exit routine and either call an atexit-style or an on_exit-style routine accordingly.
This commit is contained in:
parent
e355de817c
commit
dc824ef736
|
@ -1,3 +1,20 @@
|
|||
2002-05-15 Jeff Johnston <jjohnstn@redhat.com>
|
||||
|
||||
* libc/include/stdlib.h: Add on_exit prototype.
|
||||
* libc/include/sys/reent.h (struct _atexit): Add argument array
|
||||
and bits to track type of exit routine to support both on_exit
|
||||
and atexit.
|
||||
(_REENT_INIT_PTR): Add missing fields that won't be zeroed out
|
||||
by default and change the setting of the atexit structure.
|
||||
(_REENT_INIT)[!_REENT_SMALL]: Remove extraneous end brace.
|
||||
* libc/stdlib/on_exit.c: New file.
|
||||
* libc/stdlib/Makefile.am: Add support for on_exit.
|
||||
* libc/stdlib/Makefile.in: Regenerated.
|
||||
* libc/stdlib/atexit.c: Change to initialize types field.
|
||||
* libc/stdlib/exit.c: Change to look at types field for each
|
||||
exit routine and either call an atexit-style or an on_exit-style
|
||||
routine accordingly.
|
||||
|
||||
2002-05-13 Jeff Johnston <jjohnstn@redhat.com>
|
||||
|
||||
* libc/machine/powerpc/vfprintf.c(__VFPRINTF_R)[__ALTIVEC__]: Don't
|
||||
|
|
|
@ -108,6 +108,7 @@ int _EXFUN(system,(const char *__string));
|
|||
long _EXFUN(a64l,(const char *__input));
|
||||
char * _EXFUN(l64a,(long __input));
|
||||
char * _EXFUN(_l64a_r,(struct _reent *,long __input));
|
||||
int _EXFUN(on_exit,(_VOID (*__func)(int, _PTR),_PTR __arg));
|
||||
int _EXFUN(putenv,(const char *__string));
|
||||
int _EXFUN(_putenv_r,(struct _reent *, const char *__string));
|
||||
int _EXFUN(setenv,(const char *__string, const char *__value, int __overwrite));
|
||||
|
|
|
@ -72,11 +72,15 @@ struct _atexit {
|
|||
struct _atexit *_next; /* next in list */
|
||||
int _ind; /* next index in this table */
|
||||
void (*_fns[_ATEXIT_SIZE])(void); /* the table itself */
|
||||
void *_fnargs[_ATEXIT_SIZE]; /* fn args for on_exit */
|
||||
__uint32_t _fntypes; /* type of exit routine */
|
||||
};
|
||||
#else
|
||||
struct _atexit {
|
||||
int _ind; /* next index in this table */
|
||||
void (*_fns[_ATEXIT_SIZE])(void); /* the table itself */
|
||||
void *_fnargs[_ATEXIT_SIZE]; /* fn args for on_exit */
|
||||
__uint32_t _fntypes; /* type of exit routine */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -304,14 +308,15 @@ struct _reent
|
|||
};
|
||||
|
||||
#define _REENT_INIT(var) \
|
||||
{ &var.__sf_fake, &var.__sf_fake, &var.__sf_fake, 0, 0, _NULL, 0, 0, \
|
||||
{ (struct __sFILE *)&var.__sf_fake, (struct __sFILE *)&var.__sf_fake, \
|
||||
(struct __sFILE *)&var.__sf_fake, 0, 0, _NULL, 0, 0, \
|
||||
"C", _NULL, _NULL, 0, 0, _NULL, _NULL, _NULL, _NULL, _NULL, \
|
||||
{ 0, _NULL }, { _NULL, 0, _NULL }, 0, _NULL }
|
||||
{ 0, _NULL, _NULL, 0 }, { _NULL, 0, _NULL }, _NULL, 0, _NULL }
|
||||
|
||||
#define _REENT_INIT_PTR(var) \
|
||||
{ var->_stdin = &var->__sf_fake; \
|
||||
var->_stdout = &var->__sf_fake; \
|
||||
var->_stderr = &var->__sf_fake; \
|
||||
{ var->_stdin = (struct __sFILE *)&var->__sf_fake; \
|
||||
var->_stdout = (struct __sFILE *)&var->__sf_fake; \
|
||||
var->_stderr = (struct __sFILE *)&var->__sf_fake; \
|
||||
var->_errno = 0; \
|
||||
var->_inc = 0; \
|
||||
var->_emergency = _NULL; \
|
||||
|
@ -328,12 +333,21 @@ struct _reent
|
|||
var->_asctime_buf = _NULL; \
|
||||
var->_sig_func = _NULL; \
|
||||
var->_atexit._ind = 0; \
|
||||
var->_atexit._fns = _NULL}; \
|
||||
var->_atexit._fns[0] = _NULL; \
|
||||
var->_atexit._fnargs[0] = _NULL; \
|
||||
var->_atexit._fntypes = 0; \
|
||||
var->__sglue._next = _NULL; \
|
||||
var->__sglue._niobs = 0; \
|
||||
var->__sglue._iobs = _NULL; \
|
||||
var->__sf = 0; \
|
||||
var->_misc = _NULL; \
|
||||
var->__sf_fake._p = _NULL; \
|
||||
var->__sf_fake._r = 0; \
|
||||
var->__sf_fake._w = 0; \
|
||||
var->__sf_fake._flags = 0; \
|
||||
var->__sf_fake._file = 0; \
|
||||
var->__sf_fake._lbfsize = 0; \
|
||||
var->__sf_fake._data = _NULL; \
|
||||
}
|
||||
|
||||
/* signal info */
|
||||
|
@ -537,6 +551,15 @@ struct _reent
|
|||
var->_new._reent._mbtowc_state = 0; \
|
||||
var->_new._reent._wctomb_state = 0; \
|
||||
var->_new._reent._l64a_buf[0] = '\0'; \
|
||||
var->_atexit = _NULL; \
|
||||
var->_atexit0._ind = 0; \
|
||||
var->_atexit0._fns[0] = _NULL; \
|
||||
var->_atexit0._fntypes = 0; \
|
||||
var->_sig_func = _NULL; \
|
||||
var->__sglue._next = _NULL; \
|
||||
var->__sglue._niobs = 0; \
|
||||
var->__sglue._iobs = _NULL; \
|
||||
memset(var->__sf,0,sizeof(var->__sf)); \
|
||||
}
|
||||
|
||||
#define _REENT_CHECK_RAND48(ptr) /* nothing */
|
||||
|
|
|
@ -55,6 +55,7 @@ LIB_SOURCES = \
|
|||
mstats.c \
|
||||
mtrim.c \
|
||||
nrand48.c \
|
||||
on_exit.c \
|
||||
putenv.c \
|
||||
putenv_r.c \
|
||||
qsort.c \
|
||||
|
@ -167,6 +168,7 @@ CHEWOUT_FILES= \
|
|||
mbtowc.def \
|
||||
mlock.def \
|
||||
mstats.def \
|
||||
on_exit.def \
|
||||
qsort.def \
|
||||
rand.def \
|
||||
rand48.def \
|
||||
|
|
|
@ -153,6 +153,7 @@ LIB_SOURCES = \
|
|||
mstats.c \
|
||||
mtrim.c \
|
||||
nrand48.c \
|
||||
on_exit.c \
|
||||
putenv.c \
|
||||
putenv_r.c \
|
||||
qsort.c \
|
||||
|
@ -226,6 +227,7 @@ CHEWOUT_FILES = \
|
|||
mbtowc.def \
|
||||
mlock.def \
|
||||
mstats.def \
|
||||
on_exit.def \
|
||||
qsort.def \
|
||||
rand.def \
|
||||
rand48.def \
|
||||
|
@ -268,12 +270,13 @@ LIBS = @LIBS@
|
|||
@USE_LIBTOOL_FALSE@lcong48.o ldiv.o ldtoa.o lrand48.o malign.o malloc.o \
|
||||
@USE_LIBTOOL_FALSE@mblen.o mblen_r.o mbstowcs.o mbstowcs_r.o mbtowc.o \
|
||||
@USE_LIBTOOL_FALSE@mbtowc_r.o mlock.o mprec.o mrand48.o msize.o \
|
||||
@USE_LIBTOOL_FALSE@mstats.o mtrim.o nrand48.o putenv.o putenv_r.o \
|
||||
@USE_LIBTOOL_FALSE@qsort.o rand.o rand48.o rand_r.o realloc.o seed48.o \
|
||||
@USE_LIBTOOL_FALSE@setenv.o setenv_r.o srand48.o strdup.o strdup_r.o \
|
||||
@USE_LIBTOOL_FALSE@strtod.o strtol.o strtoll.o strtoll_r.o strtoul.o \
|
||||
@USE_LIBTOOL_FALSE@strtoull.o strtoull_r.o system.o valloc.o wcstombs.o \
|
||||
@USE_LIBTOOL_FALSE@wcstombs_r.o wctomb.o wctomb_r.o
|
||||
@USE_LIBTOOL_FALSE@mstats.o mtrim.o nrand48.o on_exit.o putenv.o \
|
||||
@USE_LIBTOOL_FALSE@putenv_r.o qsort.o rand.o rand48.o rand_r.o \
|
||||
@USE_LIBTOOL_FALSE@realloc.o seed48.o setenv.o setenv_r.o srand48.o \
|
||||
@USE_LIBTOOL_FALSE@strdup.o strdup_r.o strtod.o strtol.o strtoll.o \
|
||||
@USE_LIBTOOL_FALSE@strtoll_r.o strtoul.o strtoull.o strtoull_r.o \
|
||||
@USE_LIBTOOL_FALSE@system.o valloc.o wcstombs.o wcstombs_r.o wctomb.o \
|
||||
@USE_LIBTOOL_FALSE@wctomb_r.o
|
||||
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
||||
|
||||
@USE_LIBTOOL_TRUE@libstdlib_la_DEPENDENCIES = freer.$(oext) \
|
||||
|
@ -291,10 +294,10 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
|
|||
@USE_LIBTOOL_TRUE@ldtoa.lo lrand48.lo malign.lo malloc.lo mblen.lo \
|
||||
@USE_LIBTOOL_TRUE@mblen_r.lo mbstowcs.lo mbstowcs_r.lo mbtowc.lo \
|
||||
@USE_LIBTOOL_TRUE@mbtowc_r.lo mlock.lo mprec.lo mrand48.lo msize.lo \
|
||||
@USE_LIBTOOL_TRUE@mstats.lo mtrim.lo nrand48.lo putenv.lo putenv_r.lo \
|
||||
@USE_LIBTOOL_TRUE@qsort.lo rand.lo rand48.lo rand_r.lo realloc.lo \
|
||||
@USE_LIBTOOL_TRUE@seed48.lo setenv.lo setenv_r.lo srand48.lo strdup.lo \
|
||||
@USE_LIBTOOL_TRUE@strdup_r.lo strtod.lo strtol.lo strtoll.lo \
|
||||
@USE_LIBTOOL_TRUE@mstats.lo mtrim.lo nrand48.lo on_exit.lo putenv.lo \
|
||||
@USE_LIBTOOL_TRUE@putenv_r.lo qsort.lo rand.lo rand48.lo rand_r.lo \
|
||||
@USE_LIBTOOL_TRUE@realloc.lo seed48.lo setenv.lo setenv_r.lo srand48.lo \
|
||||
@USE_LIBTOOL_TRUE@strdup.lo strdup_r.lo strtod.lo strtol.lo strtoll.lo \
|
||||
@USE_LIBTOOL_TRUE@strtoll_r.lo strtoul.lo strtoull.lo strtoull_r.lo \
|
||||
@USE_LIBTOOL_TRUE@system.lo valloc.lo wcstombs.lo wcstombs_r.lo \
|
||||
@USE_LIBTOOL_TRUE@wctomb.lo wctomb_r.lo
|
||||
|
|
|
@ -74,6 +74,7 @@ _DEFUN (atexit,
|
|||
if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
|
||||
return -1;
|
||||
p->_ind = 0;
|
||||
p->_fntypes = 0;
|
||||
p->_next = _REENT->_atexit;
|
||||
_REENT->_atexit = p;
|
||||
}
|
||||
|
|
|
@ -61,15 +61,20 @@ _DEFUN (exit, (code),
|
|||
{
|
||||
register struct _atexit *p;
|
||||
register int n;
|
||||
int i = 1;
|
||||
|
||||
#ifdef _REENT_SMALL
|
||||
for (p = &_REENT->_atexit, n = p->_ind; --n >= 0;)
|
||||
(*p->_fns[n]) ();
|
||||
for (p = &_REENT->_atexit, n = p->_ind-1, i = (n>=0) ? (1<<n) : 0;
|
||||
n >= 0; --n, i >>= 1)
|
||||
#else
|
||||
for (p = _REENT->_atexit; p; p = p->_next)
|
||||
for (n = p->_ind; --n >= 0;)
|
||||
(*p->_fns[n]) ();
|
||||
for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1)
|
||||
#endif
|
||||
if (p->_fntypes & i)
|
||||
(*((void (*)(int, void *))p->_fns[n]))(code, p->_fnargs[n]);
|
||||
else
|
||||
(*p->_fns[n]) ();
|
||||
|
||||
if (_REENT->__cleanup)
|
||||
(*_REENT->__cleanup) (_REENT);
|
||||
_exit (code);
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 1990 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* %sccs.include.redist.c%
|
||||
*
|
||||
* This function is a modified version of atexit.c
|
||||
*/
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
<<on_exit>>---request execution of function with argument at program exit
|
||||
|
||||
INDEX
|
||||
on_exit
|
||||
|
||||
ANSI_SYNOPSIS
|
||||
#include <stdlib.h>
|
||||
int on_exit (void (*<[function]>)(int, void *), void *<[arg]>);
|
||||
|
||||
TRAD_SYNOPSIS
|
||||
#include <stdlib.h>
|
||||
int on_exit ((<[function]>, <[arg]>)
|
||||
void (*<[function]>)(int, void *);
|
||||
void *<[arg]>;
|
||||
|
||||
DESCRIPTION
|
||||
You can use <<on_exit>> to enroll functions in a list of functions that
|
||||
will be called when your program terminates normally. The argument is
|
||||
a pointer to a user-defined function which takes two arguments. The
|
||||
first is the status code passed to exit and the second argument is of type
|
||||
pointer to void. The function must not return a result. The value
|
||||
of <[arg]> is registered and passed as the argument to <[function]>.
|
||||
|
||||
The functions are kept in a LIFO stack; that is, the last function
|
||||
enrolled by <<atexit>> or <<on_exit>> will be the first to execute when
|
||||
your program exits. You can intermix functions using <<atexit>> and
|
||||
<<on_exit>>.
|
||||
|
||||
There is no built-in limit to the number of functions you can enroll
|
||||
in this list; however, after every group of 32 functions is enrolled,
|
||||
<<atexit>>/<<on_exit>> will call <<malloc>> to get space for the next part
|
||||
of the list. The initial list of 32 functions is statically allocated, so
|
||||
you can always count on at least that many slots available.
|
||||
|
||||
RETURNS
|
||||
<<on_exit>> returns <<0>> if it succeeds in enrolling your function,
|
||||
<<-1>> if it fails (possible only if no space was available for
|
||||
<<malloc>> to extend the list of functions).
|
||||
|
||||
PORTABILITY
|
||||
<<on_exit>> is a non-standard glibc extension
|
||||
|
||||
Supporting OS subroutines required: None
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <reent.h>
|
||||
|
||||
/*
|
||||
* Register a function to be performed at exit.
|
||||
*/
|
||||
|
||||
int
|
||||
_DEFUN (on_exit,
|
||||
(fn, arg),
|
||||
_VOID _EXFUN ((*fn), (int, _PTR)) _AND
|
||||
_PTR arg)
|
||||
{
|
||||
register struct _atexit *p;
|
||||
void (*x)(void) = (void (*)(void))fn;
|
||||
|
||||
/* _REENT_SMALL on_exit() doesn't allow more than the required 32 entries. */
|
||||
#ifndef _REENT_SMALL
|
||||
if ((p = _REENT->_atexit) == NULL)
|
||||
_REENT->_atexit = p = &_REENT->_atexit0;
|
||||
if (p->_ind >= _ATEXIT_SIZE)
|
||||
{
|
||||
if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL)
|
||||
return -1;
|
||||
p->_ind = 0;
|
||||
p->_fntypes = 0;
|
||||
p->_next = _REENT->_atexit;
|
||||
_REENT->_atexit = p;
|
||||
}
|
||||
#else
|
||||
p = &_REENT->_atexit;
|
||||
if (p->_ind >= _ATEXIT_SIZE)
|
||||
return -1;
|
||||
#endif
|
||||
p->_fntypes |= (1 << p->_ind);
|
||||
p->_fnargs[p->_ind] = arg;
|
||||
p->_fns[p->_ind++] = x;
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue