From dc824ef7363e46b3602b458f7bf00303601c1102 Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Wed, 15 May 2002 22:58:10 +0000 Subject: 2002-05-15 Jeff Johnston * 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. --- newlib/libc/stdlib/on_exit.c | 96 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 newlib/libc/stdlib/on_exit.c (limited to 'newlib/libc/stdlib/on_exit.c') 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 +<>---request execution of function with argument at program exit + +INDEX + on_exit + +ANSI_SYNOPSIS + #include + int on_exit (void (*<[function]>)(int, void *), void *<[arg]>); + +TRAD_SYNOPSIS + #include + int on_exit ((<[function]>, <[arg]>) + void (*<[function]>)(int, void *); + void *<[arg]>; + +DESCRIPTION +You can use <> 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 <> or <> will be the first to execute when +your program exits. You can intermix functions using <> and +<>. + +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, +<>/<> will call <> 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 +<> returns <<0>> if it succeeds in enrolling your function, +<<-1>> if it fails (possible only if no space was available for +<> to extend the list of functions). + +PORTABILITY +<> is a non-standard glibc extension + +Supporting OS subroutines required: None +*/ + +#include +#include +#include + +/* + * 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; +} -- cgit v1.2.3