about summary refs log tree commit diff
path: root/stdlib
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2009-03-08 19:53:12 +0000
committerUlrich Drepper <drepper@redhat.com>2009-03-08 19:53:12 +0000
commit610e67ed5af7e1acf2f96bb964cc2131af570a3d (patch)
tree14daa2846118122a858f3f498a525456a7d74ba0 /stdlib
parent130ca12eb3d9b2fec32847699ca08ea25aec9130 (diff)
downloadglibc-610e67ed5af7e1acf2f96bb964cc2131af570a3d.tar.gz
glibc-610e67ed5af7e1acf2f96bb964cc2131af570a3d.tar.xz
glibc-610e67ed5af7e1acf2f96bb964cc2131af570a3d.zip
* stdlib/Makefile (routines): Add quick_exit, at_quick_exit, and
	cxa_at_quick_exit.
	(static-only-routines): Add at_quick_exit.
	* stdlib/Versions: Export quick_exit and __cxa_at_quick_exit for
	GLIBC_2.10.
	* stdlib/quick_exit.c: New file.
	* stdlib/at_quick_exit.c: New file.
	* stdlib/cxa_at_quick_exit.c: New file.
	* stdlib/cxa_atexit.c (__cxa_atexit): Move body to new function.  Call
	it appropriately.
	(__internal_atexit): New function.
	(__new_exitfn): Now takes parameter to point to the list to use.
	* stdlib/cxa_finalize.c: Remove quick_exit handlers, don't call them.
	* stdlib/exit.c (__run_exit_handlers): New function.  Split from...
	(exit): ...here.  Just call __run_exit_handlers appropriately.
	* stdlib/exit.h: Declare __quick_exit_funcs, __run_exit_handlers,
	__internal_atexit, __cxa_at_quick_exit.  Adjust __new_exitfn.
	* stdlib/on_exit.c: Adjust call to __new_exitfn.
	* stdlib/stdlib.h: Declare at_quick_exit and quick_exit.
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