* src/sort.c (cleanup): Clear temphead at the end.
authorDan Hipschman <dsh@linux.ucla.edu>
Fri, 19 Jan 2007 22:03:18 +0000 (23:03 +0100)
committerJim Meyering <jim@meyering.net>
Fri, 19 Jan 2007 22:03:18 +0000 (23:03 +0100)
(exit_cleanup): New function.
(main): Don't invoke atexit until we're ready.
Invoke it with exit_cleanup, not with cleanup and close_stdout,
to avoid a race condition with cleanup and signal handling.  More
details: http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/9508

ChangeLog
src/sort.c

index 629ad5b..26d0760 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-01-19  Dan Hipschman  <dsh@linux.ucla.edu>
+       and Paul Eggert  <eggert@cs.ucla.edu>
+
+       * src/sort.c (cleanup): Clear temphead at the end.
+       (exit_cleanup): New function.
+       (main): Don't invoke atexit until we're ready.
+       Invoke it with exit_cleanup, not with cleanup and close_stdout,
+       to avoid a race condition with cleanup and signal handling.  More
+       details: http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/9508
+
 2007-01-18  Jim Meyering  <jim@meyering.net>
 
        * src/c99-to-c89.diff: Adjust remove.c offsets.
index f03237c..326866f 100644 (file)
@@ -417,6 +417,25 @@ cleanup (void)
 
   for (node = temphead; node; node = node->next)
     unlink (node->name);
+  temphead = NULL;
+}
+
+/* Cleanup actions to take when exiting.  */
+
+static void
+exit_cleanup (void)
+{
+  if (temphead)
+    {
+      /* Clean up any remaining temporary files in a critical section so
+        that a signal handler does not try to clean them too.  */
+      sigset_t oldset;
+      sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
+      cleanup ();
+      sigprocmask (SIG_SETMASK, &oldset, NULL);
+    }
+
+  close_stdout ();
 }
 
 /* Create a new temporary file, returning its newly allocated name.
@@ -2302,10 +2321,7 @@ main (int argc, char **argv)
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
 
-  atexit (cleanup);
-
   initialize_exit_failure (SORT_FAILURE);
-  atexit (close_stdout);
 
   hard_LC_COLLATE = hard_locale (LC_COLLATE);
 #if HAVE_NL_LANGINFO
@@ -2365,6 +2381,9 @@ main (int argc, char **argv)
 #endif
   }
 
+  /* The signal mask is known, so it is safe to invoke exit_cleanup.  */
+  atexit (exit_cleanup);
+
   gkey.sword = gkey.eword = SIZE_MAX;
   gkey.ignore = NULL;
   gkey.translate = NULL;