summaryrefslogtreecommitdiffstats
path: root/newlib/libc/stdlib/__call_atexit.c
diff options
context:
space:
mode:
authorKazu Hirata <kazu@codesourcery.com>2007-04-05 16:47:38 +0000
committerKazu Hirata <kazu@codesourcery.com>2007-04-05 16:47:38 +0000
commit0efa93c0616547546ef8e3abedb45534958158c9 (patch)
tree8d237319a24160b3e08cdad3b2dee87cf60b9458 /newlib/libc/stdlib/__call_atexit.c
parent263435cc613c72ccf472257d15f824523e27ac24 (diff)
downloadcygnal-0efa93c0616547546ef8e3abedb45534958158c9.tar.gz
cygnal-0efa93c0616547546ef8e3abedb45534958158c9.tar.bz2
cygnal-0efa93c0616547546ef8e3abedb45534958158c9.zip
* libc/stdlib/__call_atexit.c (__call_exitprocs): Handle atexit
functions registering additional atexit functions.
Diffstat (limited to 'newlib/libc/stdlib/__call_atexit.c')
-rw-r--r--newlib/libc/stdlib/__call_atexit.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/newlib/libc/stdlib/__call_atexit.c b/newlib/libc/stdlib/__call_atexit.c
index 6fa398ae2..ab86fcafa 100644
--- a/newlib/libc/stdlib/__call_atexit.c
+++ b/newlib/libc/stdlib/__call_atexit.c
@@ -23,6 +23,8 @@ _DEFUN (__call_exitprocs, (code, d),
int i;
void (*fn) (void);
+ restart:
+
p = _GLOBAL_REENT->_atexit;
lastp = &_GLOBAL_REENT->_atexit;
while (p)
@@ -34,6 +36,8 @@ _DEFUN (__call_exitprocs, (code, d),
#endif
for (n = p->_ind - 1; n >= 0; n--)
{
+ int ind;
+
i = 1 << n;
/* Skip functions not from this dso. */
@@ -52,6 +56,8 @@ _DEFUN (__call_exitprocs, (code, d),
if (!fn)
continue;
+ ind = p->_ind;
+
/* Call the function. */
if (!args || (args->_fntypes & i) == 0)
fn ();
@@ -59,6 +65,12 @@ _DEFUN (__call_exitprocs, (code, d),
(*((void (*)(int, _PTR)) fn))(code, args->_fnargs[n]);
else
(*((void (*)(_PTR)) fn))(args->_fnargs[n]);
+
+ /* The function we called call atexit and registered another
+ function (or functions). Call these new functions before
+ continuing with the already registered functions. */
+ if (ind != p->_ind || *lastp != p)
+ goto restart;
}
#ifndef _ATEXIT_DYNAMIC_ALLOC