diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | src/sort.c | 25 |
2 files changed, 32 insertions, 3 deletions
@@ -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; |