From c08bc50a60a92e8d32f302ea411312bc438f05ef Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 26 Feb 2001 17:53:15 +0000 Subject: Update. 2001-02-26 Ulrich Drepper * dlfcn/Makefile (distribute): Add modatexit.c and modcxaatexit.c. (tests): Add tstatexit and tstcxaatexit. (module-names): Add modatexit and modcxaatexit. Add rules to build and run tstatexit and tstcxaatexit. * dlfcn/modatexit.c: New file. * dlfcn/modcxaatexit.c: New file. * dlfcn/tstatexit.c: New file. * dlfcn/tstcxaatexit.c: New file. * io/Makefile: Pass -DHAVE_DOT_HIDDEN to stat and mknod functions if .hidden is available. * io/stat.c: If .hidden is available use it to avoid exporting functions. * io/fstat.c: Likewise. * io/lstat.c: Likewise. * io/stat64.c: Likewise. * io/fstat64.c: Likewise. * io/lstat64.c: Likewise. * sysdeps/generic/mknod.c: Likewise. * malloc/mtrace.c: Use __cxa_atexit and not atexit. * sysdeps/generic/bb_init_func.c: Likewise. * sysdeps/generic/libc-start.c: Likewise. * stdlib/atexit.c (__new_exitfn): Move to cxa_atexit.c. (atexit): Implement using __cxa_atexit. Use .hidden if availble to avoid exporting atexit. * stdlib/cxa_atexit.c (__new_exitfn): Moved to here from atexit.c. * stdlib/Versions: Export __new_exitfn for GLIBC_2.2.3. * stdlib/Makefile (routines): Add old_atexit. (static-only-routines): Add atexit. Pass -DHAVE_DOT_HIDDEN for atexit.c if .hidden is available. * stdlib/old_atexit.c: New file. * intl/Makefile: Remove bogus endif. --- stdlib/cxa_atexit.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'stdlib/cxa_atexit.c') diff --git a/stdlib/cxa_atexit.c b/stdlib/cxa_atexit.c index e07d0eda35..f602b7a1af 100644 --- a/stdlib/cxa_atexit.c +++ b/stdlib/cxa_atexit.c @@ -16,6 +16,7 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include #include "exit.h" @@ -36,3 +37,57 @@ __cxa_atexit (void (*func) (void *), void *arg, void *d) new->func.cxa.dso_handle = d; return 0; } + + +/* We change global data, so we need locking. */ +__libc_lock_define_initialized (static, lock) + + +static struct exit_function_list initial; +struct exit_function_list *__exit_funcs = &initial; + +struct exit_function * +__new_exitfn (void) +{ + struct exit_function_list *l; + size_t i = 0; + + __libc_lock_lock (lock); + + for (l = __exit_funcs; l != NULL; l = l->next) + { + for (i = 0; i < l->idx; ++i) + if (l->fns[i].flavor == ef_free) + break; + if (i < l->idx) + break; + + if (l->idx < sizeof (l->fns) / sizeof (l->fns[0])) + { + i = l->idx++; + break; + } + } + + if (l == NULL) + { + l = (struct exit_function_list *) + malloc (sizeof (struct exit_function_list)); + if (l != NULL) + { + l->next = __exit_funcs; + __exit_funcs = l; + + l->idx = 1; + i = 0; + } + } + + /* Mark entry as used, but we don't know the flavor now. */ + if (l != NULL) + l->fns[i].flavor = ef_us; + + __libc_lock_unlock (lock); + + return l == NULL ? NULL : &l->fns[i]; +} -- cgit v1.2.3