diff options
author | Nick Clifton <nickc@redhat.com> | 2003-06-06 19:36:31 +0400 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2003-06-06 19:36:31 +0400 |
commit | 75d7d177004358ba5e410a2cd98f2249b6c4e1b3 (patch) | |
tree | fc1541e54ea04ed5a4260fbc60e578424945e2ef /newlib/libc | |
parent | 54152c7e7ed656c969fe4536f17f66360cd8d971 (diff) |
New structure containing fields used by the on_exit() function.
(struct _atexit): Include struct _on_exit_args. For _REENT_SMALL do his via a
pointer that is initialised when needed.
Diffstat (limited to 'newlib/libc')
-rw-r--r-- | newlib/libc/include/sys/reent.h | 16 | ||||
-rw-r--r-- | newlib/libc/reent/reent.c | 2 | ||||
-rw-r--r-- | newlib/libc/stdlib/atexit.c | 6 | ||||
-rw-r--r-- | newlib/libc/stdlib/exit.c | 41 | ||||
-rw-r--r-- | newlib/libc/stdlib/on_exit.c | 29 |
5 files changed, 67 insertions, 27 deletions
diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h index 2d6ce4146..d1a04dc43 100644 --- a/newlib/libc/include/sys/reent.h +++ b/newlib/libc/include/sys/reent.h @@ -64,20 +64,24 @@ struct __tm #define _ATEXIT_SIZE 32 /* must be at least 32 to guarantee ANSI conformance */ -#ifndef _REENT_SMALL +struct _on_exit_args { + void * _fnargs[_ATEXIT_SIZE]; /* fn args for on_exit */ + __ULong _fntypes; /* type of exit routine - + Must have at least _ATEXIT_SIZE bits */ +}; + +#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 */ - void *_fnargs[_ATEXIT_SIZE]; /* fn args for on_exit */ - __ULong _fntypes; /* type of exit routine */ + struct _on_exit_args * _on_exit_args_ptr; }; #else 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 */ - __ULong _fntypes; /* type of exit routine */ + struct _on_exit_args _on_exit_args; }; #endif diff --git a/newlib/libc/reent/reent.c b/newlib/libc/reent/reent.c index 9300e8cd0..3ce02dcf2 100644 --- a/newlib/libc/reent/reent.c +++ b/newlib/libc/reent/reent.c @@ -81,6 +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->_atexit._on_exit_args_ptr); #else /* atexit stuff */ if ((ptr->_atexit) && (ptr->_atexit != &ptr->_atexit0)) diff --git a/newlib/libc/stdlib/atexit.c b/newlib/libc/stdlib/atexit.c index 165b3cf07..e0e42988a 100644 --- a/newlib/libc/stdlib/atexit.c +++ b/newlib/libc/stdlib/atexit.c @@ -65,16 +65,16 @@ _DEFUN (atexit, { register struct _atexit *p; -/* _REENT_SMALL atexit() doesn't allow more than the required 32 entries. */ + /* _REENT_SMALL atexit() 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; + return -1; p->_ind = 0; - p->_fntypes = 0; + p->_on_exit_args._fntypes = 0; p->_next = _REENT->_atexit; _REENT->_atexit = p; } diff --git a/newlib/libc/stdlib/exit.c b/newlib/libc/stdlib/exit.c index 54664fec5..a659361bd 100644 --- a/newlib/libc/stdlib/exit.c +++ b/newlib/libc/stdlib/exit.c @@ -60,20 +60,43 @@ _DEFUN (exit, (code), int code) { register struct _atexit *p; + register struct _on_exit_args * args; register int n; - int i = 1; + int i; + + p = &_REENT->_atexit; #ifdef _REENT_SMALL - for (p = &_REENT->_atexit, n = p->_ind-1, i = (n>=0) ? (1<<n) : 0; - n >= 0; --n, i >>= 1) + 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 - for (p = _REENT->_atexit; p; p = p->_next) - for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1) + do + { + 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; + } + while (p); #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); diff --git a/newlib/libc/stdlib/on_exit.c b/newlib/libc/stdlib/on_exit.c index 1b6cd2abe..b7bf6f304 100644 --- a/newlib/libc/stdlib/on_exit.c +++ b/newlib/libc/stdlib/on_exit.c @@ -68,29 +68,40 @@ _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. */ -#ifndef _REENT_SMALL +#ifdef _REENT_SMALL + p = &_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 = _REENT->_atexit) == NULL) _REENT->_atexit = p = &_REENT->_atexit0; if (p->_ind >= _ATEXIT_SIZE) { if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL) - return -1; + return -1; p->_ind = 0; - p->_fntypes = 0; + p->_on_exit_args._fntypes = 0; p->_next = _REENT->_atexit; _REENT->_atexit = p; } -#else - p = &_REENT->_atexit; - if (p->_ind >= _ATEXIT_SIZE) - return -1; + args = & p->_on_exit_args; #endif - p->_fntypes |= (1 << p->_ind); - p->_fnargs[p->_ind] = arg; + args->_fntypes |= (1 << p->_ind); + args->_fnargs[p->_ind] = arg; p->_fns[p->_ind++] = x; return 0; } |