aboutsummaryrefslogtreecommitdiff
path: root/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/Makefile5
-rw-r--r--stdlib/Versions3
-rw-r--r--stdlib/at_quick_exit.c50
-rw-r--r--stdlib/cxa_at_quick_exit.c32
-rw-r--r--stdlib/cxa_atexit.c30
-rw-r--r--stdlib/cxa_finalize.c12
-rw-r--r--stdlib/exit.c32
-rw-r--r--stdlib/exit.h16
-rw-r--r--stdlib/on_exit.c4
-rw-r--r--stdlib/quick_exit.c30
-rw-r--r--stdlib/stdlib.h23
11 files changed, 208 insertions, 29 deletions
diff --git a/stdlib/Makefile b/stdlib/Makefile
index a69bdaeb73..d361dd8ffa 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2006, 2007, 2008 Free Software Foundation, Inc.
+# Copyright (C) 1991-2006, 2007, 2008, 2009 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@@ -34,6 +34,7 @@ routines := \
bsearch qsort msort \
getenv putenv setenv secure-getenv \
exit on_exit atexit cxa_atexit cxa_finalize old_atexit \
+ quick_exit at_quick_exit cxa_at_quick_exit \
abs labs llabs \
div ldiv lldiv \
mblen mbstowcs mbtowc wcstombs wctomb \
@@ -57,7 +58,7 @@ aux = grouping groupingwc tens_in_limb
# These routines will be omitted from the libc shared object.
# Instead the static object files will be included in a special archive
# linked against when the shared library will be used.
-static-only-routines = atexit
+static-only-routines = atexit at_quick_exit
distribute := exit.h grouping.h abort-instr.h isomac.c tst-fmtmsg.sh \
allocalim.h
diff --git a/stdlib/Versions b/stdlib/Versions
index f4a90c9d69..93c68f6e31 100644
--- a/stdlib/Versions
+++ b/stdlib/Versions
@@ -97,6 +97,9 @@ libc {
GLIBC_2.8 {
qsort_r;
}
+ GLIBC_2.10 {
+ quick_exit; __cxa_at_quick_exit;
+ }
GLIBC_PRIVATE {
# functions which have an additional interface since they are
# are cancelable.
diff --git a/stdlib/at_quick_exit.c b/stdlib/at_quick_exit.c
new file mode 100644
index 0000000000..abe2910a7b
--- /dev/null
+++ b/stdlib/at_quick_exit.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 1991,1996,1999,2001,2006,2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+#include "exit.h"
+
+
+/* This is defined by newer gcc version unique for each module. */
+extern void *__dso_handle __attribute__ ((__weak__));
+
+
+/* Register FUNC to be executed by `quick_exit'. */
+int
+at_quick_exit (void (*func) (void))
+{
+ return __cxa_at_quick_exit ((void (*) (void *)) func,
+ &__dso_handle == NULL ? NULL : __dso_handle);
+}
diff --git a/stdlib/cxa_at_quick_exit.c b/stdlib/cxa_at_quick_exit.c
new file mode 100644
index 0000000000..45c5f5e84c
--- /dev/null
+++ b/stdlib/cxa_at_quick_exit.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+#include "exit.h"
+
+
+static struct exit_function_list initial_quick;
+struct exit_function_list *__quick_exit_funcs = &initial_quick;
+
+/* Register a function to be called by quick_exit. */
+int
+attribute_hidden
+__cxa_at_quick_exit (void (*func) (void *), void *d)
+{
+ return __internal_atexit (func, NULL, d, &__quick_exit_funcs);
+}
diff --git a/stdlib/cxa_atexit.c b/stdlib/cxa_atexit.c
index 3bdf871e53..767f08e66b 100644
--- a/stdlib/cxa_atexit.c
+++ b/stdlib/cxa_atexit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 1999,2001,2002,2005,2006,2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -26,13 +26,13 @@
#undef __cxa_atexit
-/* Register a function to be called by exit or when a shared library
- is unloaded. This function is only called from code generated by
- the C++ compiler. */
+
int
-__cxa_atexit (void (*func) (void *), void *arg, void *d)
+attribute_hidden
+__internal_atexit (void (*func) (void *), void *arg, void *d,
+ struct exit_function_list **listp)
{
- struct exit_function *new = __new_exitfn ();
+ struct exit_function *new = __new_exitfn (listp);
if (new == NULL)
return -1;
@@ -47,6 +47,16 @@ __cxa_atexit (void (*func) (void *), void *arg, void *d)
new->flavor = ef_cxa;
return 0;
}
+
+
+/* Register a function to be called by exit or when a shared library
+ is unloaded. This function is only called from code generated by
+ the C++ compiler. */
+int
+__cxa_atexit (void (*func) (void *), void *arg, void *d)
+{
+ return __internal_atexit (func, arg, d, &__exit_funcs);
+}
INTDEF(__cxa_atexit)
@@ -59,7 +69,7 @@ struct exit_function_list *__exit_funcs = &initial;
uint64_t __new_exitfn_called;
struct exit_function *
-__new_exitfn (void)
+__new_exitfn (struct exit_function_list **listp)
{
struct exit_function_list *p = NULL;
struct exit_function_list *l;
@@ -68,7 +78,7 @@ __new_exitfn (void)
__libc_lock_lock (lock);
- for (l = __exit_funcs; l != NULL; p = l, l = l->next)
+ for (l = *listp; l != NULL; p = l, l = l->next)
{
for (i = l->idx; i > 0; --i)
if (l->fns[i - 1].flavor != ef_free)
@@ -92,8 +102,8 @@ __new_exitfn (void)
calloc (1, sizeof (struct exit_function_list));
if (p != NULL)
{
- p->next = __exit_funcs;
- __exit_funcs = p;
+ p->next = *listp;
+ *listp = p;
}
}
diff --git a/stdlib/cxa_finalize.c b/stdlib/cxa_finalize.c
index 148d57f200..351538a686 100644
--- a/stdlib/cxa_finalize.c
+++ b/stdlib/cxa_finalize.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999,2001,2002,2003,2005,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1999,2001-2003,2005,2006,2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -63,6 +63,16 @@ __cxa_finalize (void *d)
}
}
+ /* Also remove the quick_exit handlers, but do not call them. */
+ for (funcs = __quick_exit_funcs; funcs; funcs = funcs->next)
+ {
+ struct exit_function *f;
+
+ for (f = &funcs->fns[funcs->idx - 1]; f >= &funcs->fns[0]; --f)
+ if (d == NULL || d == f->func.cxa.dso_handle)
+ f->flavor = ef_free;
+ }
+
/* Remove the registered fork handlers. We do not have to
unregister anything if the program is going to terminate anyway. */
#ifdef UNREGISTER_ATFORK
diff --git a/stdlib/exit.c b/stdlib/exit.c
index bc4cb0fd08..539ae4bd7e 100644
--- a/stdlib/exit.c
+++ b/stdlib/exit.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,95,96,97,99,2001,2002,2005 Free Software Foundation, Inc.
+/* Copyright (C) 1991,95,96,97,99,2001,2002,2005,2009
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -30,20 +31,22 @@ DEFINE_HOOK (__libc_atexit, (void))
in the reverse of the order in which they were registered
perform stdio cleanup, and terminate program execution with STATUS. */
void
-exit (int status)
+attribute_hidden
+__run_exit_handlers (int status, struct exit_function_list **listp,
+ bool run_list_atexit)
{
/* We do it this way to handle recursive calls to exit () made by
the functions registered with `atexit' and `on_exit'. We call
everyone on the list and use the status value in the last
exit (). */
- while (__exit_funcs != NULL)
+ while (*listp != NULL)
{
- struct exit_function_list *old;
+ struct exit_function_list *cur = *listp;
- while (__exit_funcs->idx > 0)
+ while (cur->idx > 0)
{
const struct exit_function *const f =
- &__exit_funcs->fns[--__exit_funcs->idx];
+ &cur->fns[--cur->idx];
switch (f->flavor)
{
void (*atfct) (void);
@@ -77,16 +80,23 @@ exit (int status)
}
}
- old = __exit_funcs;
- __exit_funcs = __exit_funcs->next;
- if (__exit_funcs != NULL)
+ *listp = cur->next;
+ if (*listp != NULL)
/* Don't free the last element in the chain, this is the statically
allocate element. */
- free (old);
+ free (cur);
}
- RUN_HOOK (__libc_atexit, ());
+ if (run_list_atexit)
+ RUN_HOOK (__libc_atexit, ());
_exit (status);
}
+
+
+void
+exit (int status)
+{
+ __run_exit_handlers (status, __exit_funcs, true);
+}
libc_hidden_def (exit)
diff --git a/stdlib/exit.h b/stdlib/exit.h
index 779675d134..948948d19b 100644
--- a/stdlib/exit.h
+++ b/stdlib/exit.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,1996,1997,1999,2001,2002,2006
+/* Copyright (C) 1991,1996,1997,1999,2001,2002,2006,2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -20,6 +20,7 @@
#ifndef _EXIT_H
#define _EXIT_H 1
+#include <stdbool.h>
#include <stdint.h>
enum
@@ -59,8 +60,19 @@ struct exit_function_list
struct exit_function fns[32];
};
extern struct exit_function_list *__exit_funcs attribute_hidden;
+extern struct exit_function_list *__quick_exit_funcs attribute_hidden;
-extern struct exit_function *__new_exitfn (void);
+extern struct exit_function *__new_exitfn (struct exit_function_list **listp);
extern uint64_t __new_exitfn_called attribute_hidden;
+extern void __run_exit_handlers (int status, struct exit_function_list **listp,
+ bool run_list_atexit) attribute_hidden;
+
+extern int __internal_atexit (void (*func) (void *), void *arg, void *d,
+ struct exit_function_list **listp)
+ attribute_hidden;
+extern int __cxa_at_quick_exit (void (*func) (void *), void *d)
+ attribute_hidden;
+
+
#endif /* exit.h */
diff --git a/stdlib/on_exit.c b/stdlib/on_exit.c
index e777604084..6a99bfa087 100644
--- a/stdlib/on_exit.c
+++ b/stdlib/on_exit.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996, 2005, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -25,7 +25,7 @@
int
__on_exit (void (*func) (int status, void *arg), void *arg)
{
- struct exit_function *new = __new_exitfn ();
+ struct exit_function *new = __new_exitfn (&__exit_funcs);
if (new == NULL)
return -1;
diff --git a/stdlib/quick_exit.c b/stdlib/quick_exit.c
new file mode 100644
index 0000000000..20cb409b7d
--- /dev/null
+++ b/stdlib/quick_exit.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sysdep.h>
+#include "exit.h"
+
+
+void
+quick_exit (int status)
+{
+ __run_exit_handlers (status, __quick_exit_funcs, false);
+}
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index ff249ad4cb..77bb860454 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -515,6 +515,18 @@ extern void abort (void) __THROW __attribute__ ((__noreturn__));
/* Register a function to be called when `exit' is called. */
extern int atexit (void (*__func) (void)) __THROW __nonnull ((1));
+
+#ifdef __USE_GNU
+// XXX There should be a macro to signal with C++ revision is used.
+// XXX This function is in the C++1x revision.
+/* Register a function to be called when `quick_exit' is called. */
+# ifdef __cplusplus
+extern "C++" int at_quick_exit (void (*__func) (void))
+ __THROW __asm ("at_quick_exit") __nonnull ((1));
+# else
+extern int at_quick_exit (void (*__func) (void)) __THROW __nonnull ((1));
+# endif
+#endif
__END_NAMESPACE_STD
#ifdef __USE_MISC
@@ -526,9 +538,18 @@ extern int on_exit (void (*__func) (int __status, void *__arg), void *__arg)
__BEGIN_NAMESPACE_STD
/* Call all functions registered with `atexit' and `on_exit',
- in the reverse of the order in which they were registered
+ in the reverse of the order in which they were registered,
perform stdio cleanup, and terminate program execution with STATUS. */
extern void exit (int __status) __THROW __attribute__ ((__noreturn__));
+
+#ifdef __USE_GNU
+// XXX There should be a macro to signal with C++ revision is used.
+// XXX This function is in the C++1x revision.
+/* Call all functions registered with `at_quick_exit' in the reverse
+ of the order in which they were registered and terminate program
+ execution with STATUS. */
+extern void quick_exit (int __status) __THROW __attribute__ ((__noreturn__));
+#endif
__END_NAMESPACE_STD
#ifdef __USE_ISOC99