#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). */
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);
close_output_file ();
sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
- delete_all_files ();
+ delete_all_files (false);
sigprocmask (SIG_SETMASK, &oldset, NULL);
}
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);
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;
}
must be called only from critical sections. */
static void
-delete_all_files (void)
+delete_all_files (bool in_signal_handler)
{
unsigned int i;
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);
}
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);
#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
}