libiberty/atexit fix

Philippe De Muyter phdm@macqel.be
Sun Oct 31 07:53:00 GMT 1999


Symptom :
cc -o fixincl fixincl.o server.o procopen.o gnu-regex.o fixlib.o ../../libiberty
/libiberty.a ../../libiberty/libiberty.a
server.o: In function `server_setup':
server.c:224: undefined reference to `atexit'

Fix :
Sun Oct 31 16:03:21 1999  Philippe De Muyter  <phdm@macqel.be>

	* atexit.c (atexit): Provide a fallback even without HAVE_ON_EXIT.

--- ./libiberty/atexit.c	Sun Oct 31 16:49:38 1999
+++ ./libiberty/atexit.c	Sun Oct 31 16:48:39 1999
@@ -1,10 +1,27 @@
-/* Wrapper to implement ANSI C's atexit using SunOS's on_exit. */
-/* This function is in the public domain.  --Mike Stump. */
+/* atexit.c -- Register a function to be called at exit.
+   Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB.  If not, write
+to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
 
 #ifdef HAVE_ON_EXIT
 
+/* Wrapper to implement ANSI C's atexit using SunOS's on_exit - Mike Stump */
 int
 atexit(f)
      void (*f)();
@@ -13,6 +30,64 @@ atexit(f)
      if the system provides that.  */
   on_exit (f, 0);
   return 0;
+}
+
+#else
+
+/* Functions to implement ANSI C's atexit from scratch - taken from libgcc2.c */
+# include <errno.h>
+
+#define volatile /**/
+
+typedef void (*func_ptr) ();
+static func_ptr *atexit_chain = 0;
+static long atexit_chain_length = 0;
+static volatile long last_atexit_chain_slot = -1;
+
+int
+atexit (func)
+     func_ptr func;
+{
+  if (++last_atexit_chain_slot == atexit_chain_length)
+    {
+      atexit_chain_length += 32;
+      if (atexit_chain)
+	atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
+					     * sizeof (func_ptr));
+      else
+	atexit_chain = (func_ptr *) malloc (atexit_chain_length
+					    * sizeof (func_ptr));
+      if (! atexit_chain)
+	{
+	  atexit_chain_length = 0;
+	  last_atexit_chain_slot = -1;
+	  errno = ENOMEM;
+	  return (-1);
+	}
+    }
+  atexit_chain[last_atexit_chain_slot] = func;
+  return (0);
+}
+
+extern void _cleanup ();
+extern void _exit ();
+
+void 
+exit (status)
+     int status;
+{
+  if (atexit_chain)
+    {
+      for ( ; last_atexit_chain_slot-- >= 0; )
+	{
+	  (*atexit_chain[last_atexit_chain_slot + 1]) ();
+	  atexit_chain[last_atexit_chain_slot + 1] = 0;
+	}
+      free (atexit_chain);
+      atexit_chain = 0;
+    }
+  _cleanup ();
+  _exit (status);
 }
 
 #endif


More information about the Gcc-patches mailing list