diff options
author | Dan Hipschman <dsh@linux.ucla.edu> | 2007-01-19 23:03:18 +0100 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2007-01-19 23:03:18 +0100 |
commit | e175f0d5b2fe8e46409a60472a90fc9ee3ec605b (patch) | |
tree | 3f89bf46c05493200a07c258bf151f9686eb2731 /src | |
parent | fd77348fefb4d834e6945ee11190ce7b4a9224a1 (diff) | |
download | coreutils-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.c | 25 |
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; |