diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2002-05-15 22:58:10 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2002-05-15 22:58:10 +0000 |
commit | dc824ef7363e46b3602b458f7bf00303601c1102 (patch) | |
tree | e323a2db83cf227cf6ddd465d8657d9339d15369 /newlib/libc/stdlib/on_exit.c | |
parent | e355de817c95c1b5b3fa98c0e5e2863a1ecb7679 (diff) | |
download | cygnal-dc824ef7363e46b3602b458f7bf00303601c1102.tar.gz cygnal-dc824ef7363e46b3602b458f7bf00303601c1102.tar.bz2 cygnal-dc824ef7363e46b3602b458f7bf00303601c1102.zip |
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.
Diffstat (limited to 'newlib/libc/stdlib/on_exit.c')
-rw-r--r-- | newlib/libc/stdlib/on_exit.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/newlib/libc/stdlib/on_exit.c b/newlib/libc/stdlib/on_exit.c new file mode 100644 index 000000000..1b6cd2abe --- /dev/null +++ b/newlib/libc/stdlib/on_exit.c @@ -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; +} |