summaryrefslogtreecommitdiff
path: root/src
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 /src
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
Diffstat (limited to 'src')
-rw-r--r--src/sort.c25
1 files changed, 22 insertions, 3 deletions
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;