summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Hipschman <dsh@linux.ucla.edu>2007-01-19 23:03:18 +0100
committerJim Meyering <jim@meyering.net>2007-01-19 23:03:18 +0100
commite175f0d5b2fe8e46409a60472a90fc9ee3ec605b (patch)
tree3f89bf46c05493200a07c258bf151f9686eb2731
parentfd77348fefb4d834e6945ee11190ce7b4a9224a1 (diff)
downloadcoreutils-e175f0d5b2fe8e46409a60472a90fc9ee3ec605b.tar.xz
* 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
-rw-r--r--ChangeLog10
-rw-r--r--src/sort.c25
2 files changed, 32 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 629ad5be8..26d0760a6 100644
--- 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.
diff --git a/src/sort.c b/src/sort.c
index f03237cb3..326866f29 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -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;