diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2005-04-09 04:55:05 +0000 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2005-04-09 04:55:05 +0000 |
commit | f33b6dab82e7c953ae684a5abe9632a4d8745b0b (patch) | |
tree | 75c476403f8eda29c9f3481da95f4cfcf026d2ba /src | |
parent | 65d8e81ce79f6a84cc51584bdb42d25c5b060f20 (diff) | |
download | coreutils-f33b6dab82e7c953ae684a5abe9632a4d8745b0b.tar.xz |
(SA_NOCLDSTOP): Define to 0 if not defined.
All uses changed.
(siginterrupt) [!HAVE_SIGINTERRUPT]: New macro.
(delete_all_files): New arg IN_SIGNAL_HANDLER, to avoid undefined
behavior when called from a signal handler. All uses changed.
(main) [!defined SA_NOCLDSTOP]:
Use siginterrupt to specify that system calls should be interrupted.
Diffstat (limited to 'src')
-rw-r--r-- | src/csplit.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/src/csplit.c b/src/csplit.c index b138ff65b..acc83b11b 100644 --- a/src/csplit.c +++ b/src/csplit.c @@ -35,9 +35,15 @@ #include "quote.h" #include "xstrtol.h" +/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is + present. */ #ifndef SA_NOCLDSTOP +# define SA_NOCLDSTOP 0 # define sigprocmask(How, Set, Oset) /* empty */ # define sigset_t int +# if ! HAVE_SIGINTERRUPT +# define siginterrupt(sig, flag) /* empty */ +# endif #endif /* The official name of this program (e.g., no `g' prefix). */ @@ -116,7 +122,7 @@ struct buffer_record static void close_output_file (void); static void create_output_file (void); -static void delete_all_files (void); +static void delete_all_files (bool); static void save_line_to_file (const struct cstring *line); void usage (int status); @@ -215,7 +221,7 @@ cleanup (void) close_output_file (); sigprocmask (SIG_BLOCK, &caught_signals, &oldset); - delete_all_files (); + delete_all_files (false); sigprocmask (SIG_SETMASK, &oldset, NULL); } @@ -237,11 +243,10 @@ xalloc_die (void) static void interrupt_handler (int sig) { -#ifndef SA_NOCLDSTOP - signal (sig, SIG_IGN); -#endif + if (! SA_NOCLDSTOP) + signal (sig, SIG_IGN); - delete_all_files (); + delete_all_files (true); signal (sig, SIG_DFL); raise (sig); @@ -903,16 +908,21 @@ split_file (void) close_output_file (); } -/* Return the name of output file number NUM. */ +/* Return the name of output file number NUM. + + This function is called from a signal handler, so it should invoke + only reentrant functions that are async-signal-safe. POSIX does + not guarantee this for the functions called below, but we don't + know of any hosts where this implementation isn't safe. */ static char * make_filename (unsigned int num) { strcpy (filename_space, prefix); if (suffix) - sprintf (filename_space+strlen(prefix), suffix, num); + sprintf (filename_space + strlen (prefix), suffix, num); else - sprintf (filename_space+strlen(prefix), "%0*u", digits, num); + sprintf (filename_space + strlen (prefix), "%0*u", digits, num); return filename_space; } @@ -947,7 +957,7 @@ create_output_file (void) must be called only from critical sections. */ static void -delete_all_files (void) +delete_all_files (bool in_signal_handler) { unsigned int i; @@ -957,7 +967,7 @@ delete_all_files (void) for (i = 0; i < files_created; i++) { const char *name = make_filename (i); - if (unlink (name)) + if (unlink (name) != 0 && !in_signal_handler) error (0, errno, "%s", name); } @@ -1397,7 +1407,7 @@ main (int argc, char **argv) static int const sig[] = { SIGHUP, SIGINT, SIGQUIT, SIGTERM }; enum { nsigs = sizeof sig / sizeof sig[0] }; -#ifdef SA_NOCLDSTOP +#if SA_NOCLDSTOP struct sigaction act; sigemptyset (&caught_signals); @@ -1418,7 +1428,10 @@ main (int argc, char **argv) #else for (i = 0; i < nsigs; i++) if (signal (sig[i], SIG_IGN) != SIG_IGN) - signal (sig[i], interrupt_handler); + { + signal (sig[i], interrupt_handler); + siginterrupt (sig[i], 1); + } #endif } |