From 0efa93c0616547546ef8e3abedb45534958158c9 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Thu, 5 Apr 2007 16:47:38 +0000 Subject: [PATCH] * libc/stdlib/__call_atexit.c (__call_exitprocs): Handle atexit functions registering additional atexit functions. --- newlib/ChangeLog | 5 +++++ newlib/libc/stdlib/__call_atexit.c | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 7c9261b10..280580e41 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,8 @@ +2007-04-04 Mark Mitchell + + * libc/stdlib/__call_atexit.c (__call_exitprocs): Handle atexit + functions registering additional atexit functions. + 2007-04-04 Patrick Mansfield * libc/machine/spu/sys/syscall.h: New file for __send_to_ppe 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