bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

signal-handling cleanup for csplit, install, ls, nohup, sort, tee


From: Paul Eggert
Subject: signal-handling cleanup for csplit, install, ls, nohup, sort, tee
Date: Mon, 19 Apr 2004 00:55:24 -0700
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

I reviewed coreutils for signal-handling bugs (e.g., race conditions)
and came up with the following proposed patch for coreutils.  This
patch is relative to CVS coreutils.  The only possibly-controversial
bit is the change to "tee".

This patch does not cover the "dd" command, which contains the most
signal-handling problems.  I'll send separate email about "dd".

2004-04-18  Paul Eggert  <address@hidden>

        Signal-handling cleanup for coreutils.  Here are the highlights:

         - csplit sometimes failed to remove files when interrupted.
         - csplit didn't clean up if two signals arrived nearly simultaneously.
         - install -s failed on System V if SIGCHLD was ignored.
         - ls could incorrectly restore color if multiple signals
           arrived nearly simultaneously.
         - tee ignored SIGPIPE, but POSIX doesn't allow this.

        * lib/nanosleep.c (suspended): Change its type from int to
        sigatomic_t volatile.
        (first_call): Make it private to rpl_nanosleep, and have it
        be zero initially as that's a bit faster.
        (my_usleep): Round up fractional times instead of truncating them,
        as this is the usual meaning for 'sleep'.

        * src/csplit.c (sigprocmask, sigset_t) [!defined SA_NOCLDSTOP]:
        Define.
        (filename_space, prefix, suffix, digits, files_created, remove_files):
        Now volatile.
        (caught_signals): New var.
        (cleanup): Block signals while deleting all files.
        (cleanup_fatal, handle_line_error, regexp_error):
        Mark with ATTRIBUTE_NORETURN.
        (create_output_file, close_output_file, interrupt_handler):
        Block signals while changing the number of output files,
        to fix some race conditions.
        (delete_all_files): Do nothing if remove_files is zero.
        Clear files_created.
        (main): Don't mess with signals until after argument processing
        is done.

        * src/csplit.c (main): Rewrite signal-catching code to make it
        similar to other coreutils programs.  When processing signals,
        block all signals that we catch, but do not block signals that we
        don't catch.  Avoid problems with unsigned int warnings.
        * src/ls.c (main): Likewise.
        * src/sort.c (main): Likewise.

        * src/csplit.c (interrupt_handler):
        Use void, not (obsolete) RETSIGTYPE.
        * src/shred.c (sigill_handler, isaac_seed_machdep): Likewise.
        
        * src/csplit.c (interrupt_handler) [defined SA_NOCLDSTOP]:
        Use simpler "signal (sig, SIG_DFL)" rather than sigaction equivalent.
        * src/ls.c (sighandler) [defined SA_NOCLDSTOP]: Likewise.
        * src/sort.c (sighandler) [defined SA_NOCLDSTOP]: Likewise.
        * src/nohup.c (main) [!defined _POSIX_SOURCE]: Likewise, except
        for SIG_IGN.
        * src/tee.c (main) [!defined _POSIX_SOURCE]: Likewise.
        
        * src/install.c: Include <signal.h>.
        (main) [defined SIGCHLD]: Ignore SIGCHLD if -s is given, since
        System V fork+wait does not work if SIGCHLD is ignored.

        * src/ls.c (sighandler) [!defined SA_NOCLDSTOP]: Reset signal
        handler to self, not to SIG_IGN, since SIGTSTP can be received
        more than once.
        (main): Use SA_RESTART, as that is simpler than checking for EINTR
        failures all over the place.

        * src/tee.c (main): Do not ignore SIGPIPE, as POSIX 1003.1-2001
        does not allow this.  This undoes the 1996-10-24 patch.

Index: NEWS
===================================================================
RCS file: /home/meyering/coreutils/cu/NEWS,v
retrieving revision 1.201
diff -p -u -r1.201 NEWS
--- NEWS        12 Apr 2004 09:20:47 -0000      1.201
+++ NEWS        19 Apr 2004 05:39:52 -0000
@@ -7,6 +7,9 @@ GNU coreutils NEWS                      
   ptx now diagnoses invalid values for its --width=N (-w)
   and --gap-size=N (-g) options.
 
+  tee now exits when it gets a SIGPIPE signal, as POSIX requires.
+  To get tee's old behavior, use the shell command "(trap '' PIPE; tee)".
+
 ** New features
 
   cp -pu and mv -u (when copying) now don't bother to update the
Index: lib/nanosleep.c
===================================================================
RCS file: /home/meyering/coreutils/cu/lib/nanosleep.c,v
retrieving revision 1.11
diff -p -u -r1.11 nanosleep.c
--- lib/nanosleep.c     1 Mar 2002 23:19:28 -0000       1.11
+++ lib/nanosleep.c     15 Apr 2004 16:26:36 -0000
@@ -1,5 +1,5 @@
 /* Provide a replacement for the POSIX nanosleep function.
-   Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -45,8 +45,7 @@ extern int errno;
 
 #include "timespec.h"
 
-static int suspended;
-int first_call = 1;
+static sig_atomic_t volatile suspended;
 
 /* Handle SIGCONT. */
 
@@ -63,7 +62,12 @@ my_usleep (const struct timespec *ts_del
 {
   struct timeval tv_delay;
   tv_delay.tv_sec = ts_delay->tv_sec;
-  tv_delay.tv_usec = ts_delay->tv_nsec / 1000;
+  tv_delay.tv_usec = (ts_delay->tv_nsec + 999) / 1000;
+  if (tv_delay.tv_usec == 1000000)
+    {
+      tv_delay.tv_sec++;
+      tv_delay.tv_usec = 0;
+    }
   select (0, (void *) 0, (void *) 0, (void *) 0, &tv_delay);
 }
 
@@ -73,6 +77,8 @@ int
 rpl_nanosleep (const struct timespec *requested_delay,
               struct timespec *remaining_delay)
 {
+  static int initialized;
+
 #ifdef SA_NOCLDSTOP
   struct sigaction oldact, newact;
 #endif
@@ -80,7 +86,7 @@ rpl_nanosleep (const struct timespec *re
   suspended = 0;
 
   /* set up sig handler */
-  if (first_call)
+  if (! initialized)
     {
 #ifdef SA_NOCLDSTOP
       newact.sa_handler = sighandler;
@@ -94,7 +100,7 @@ rpl_nanosleep (const struct timespec *re
       if (signal (SIGCONT, SIG_IGN) != SIG_IGN)
        signal (SIGCONT, sighandler);
 #endif
-      first_call = 0;
+      initialized = 1;
     }
 
   my_usleep (requested_delay);
Index: src/csplit.c
===================================================================
RCS file: /home/meyering/coreutils/cu/src/csplit.c,v
retrieving revision 1.126
diff -p -u -r1.126 csplit.c
--- src/csplit.c        21 Jan 2004 22:49:36 -0000      1.126
+++ src/csplit.c        15 Apr 2004 16:49:25 -0000
@@ -34,6 +34,11 @@
 #include "safe-read.h"
 #include "xstrtol.h"
 
+#ifndef SA_NOCLDSTOP
+# define sigprocmask(How, Set, Oset) /* empty */
+# define sigset_t int
+#endif
+
 /* The official name of this program (e.g., no `g' prefix).  */
 #define PROGRAM_NAME "csplit"
 
@@ -139,19 +144,19 @@ static uintmax_t current_line = 0;
 static bool have_read_eof = false;
 
 /* Name of output files. */
-static char *filename_space = NULL;
+static char * volatile filename_space = NULL;
 
 /* Prefix part of output file names. */
-static char *prefix = NULL;
+static char * volatile prefix = NULL;
 
 /* Suffix part of output file names. */
-static char *suffix = NULL;
+static char * volatile suffix = NULL;
 
 /* Number of digits to use in output file names. */
-static int digits = 2;
+static int volatile digits = 2;
 
 /* Number of files created so far. */
-static unsigned int files_created = 0;
+static unsigned int volatile files_created = 0;
 
 /* Number of bytes written to current file. */
 static uintmax_t bytes_written;
@@ -169,7 +174,7 @@ static char **global_argv;
 static bool suppress_count;
 
 /* If true, remove output files on error. */
-static bool remove_files;
+static bool volatile remove_files;
 
 /* If true, remove all output files which have a zero length. */
 static bool elide_empty_files;
@@ -181,6 +186,9 @@ static struct control *controls;
 /* Number of elements in `controls'. */
 static size_t control_used;
 
+/* The set of signals that are caught.  */
+static sigset_t caught_signals;
+
 static struct option const longopts[] =
 {
   {"digits", required_argument, NULL, 'n'},
@@ -201,12 +209,16 @@ static struct option const longopts[] =
 static void
 cleanup (void)
 {
+  sigset_t oldset;
+
   close_output_file ();
 
-  if (remove_files)
-    delete_all_files ();
+  sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
+  delete_all_files ();
+  sigprocmask (SIG_SETMASK, &oldset, NULL);
 }
 
+static void cleanup_fatal (void) ATTRIBUTE_NORETURN;
 static void
 cleanup_fatal (void)
 {
@@ -214,20 +226,16 @@ cleanup_fatal (void)
   exit (EXIT_FAILURE);
 }
 
-static RETSIGTYPE
+static void
 interrupt_handler (int sig)
 {
-#ifdef SA_NOCLDSTOP
-  struct sigaction sigact;
+#ifndef SA_NOCLDSTOP
+  signal (sig, SIG_IGN);
+#endif
+
+  delete_all_files ();
 
-  sigact.sa_handler = SIG_DFL;
-  sigemptyset (&sigact.sa_mask);
-  sigact.sa_flags = 0;
-  sigaction (sig, &sigact, NULL);
-#else
   signal (sig, SIG_DFL);
-#endif
-  cleanup ();
   raise (sig);
 }
 
@@ -681,6 +689,8 @@ dump_rest_of_file (void)
 /* Handle an attempt to read beyond EOF under the control of record P,
    on iteration REPETITION if nonzero. */
 
+static void handle_line_error (const struct control *, uintmax_t)
+     ATTRIBUTE_NORETURN;
 static void
 handle_line_error (const struct control *p, uintmax_t repetition)
 {
@@ -728,6 +738,7 @@ process_line_count (const struct control
     handle_line_error (p, repetition);
 }
 
+static void regexp_error (struct control *, uintmax_t, bool) 
ATTRIBUTE_NORETURN;
 static void
 regexp_error (struct control *p, uintmax_t repetition, bool ignore)
 {
@@ -902,30 +913,47 @@ make_filename (unsigned int num)
 static void
 create_output_file (void)
 {
+  sigset_t oldset;
+  bool fopen_ok;
+  int fopen_errno;
+
   output_filename = make_filename (files_created);
+
+  /* Create the output file in a critical section, to avoid races.  */
+  sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
   output_stream = fopen (output_filename, "w");
-  if (output_stream == NULL)
+  fopen_ok = (output_stream != NULL);
+  fopen_errno = errno;
+  files_created += fopen_ok;
+  sigprocmask (SIG_SETMASK, &oldset, NULL);
+
+  if (! fopen_ok)
     {
-      error (0, errno, "%s", output_filename);
+      error (0, fopen_errno, "%s", output_filename);
       cleanup_fatal ();
     }
-  files_created++;
   bytes_written = 0;
 }
 
-/* Delete all the files we have created. */
+/* If requested, delete all the files we have created.  This function
+   must be called only from critical sections.  */
 
 static void
 delete_all_files (void)
 {
   unsigned int i;
 
+  if (! remove_files)
+    return;
+    
   for (i = 0; i < files_created; i++)
     {
       const char *name = make_filename (i);
       if (unlink (name))
        error (0, errno, "%s", name);
     }
+
+  files_created = 0;
 }
 
 /* Close the current output file and print the count
@@ -950,9 +978,19 @@ close_output_file (void)
        }
       if (bytes_written == 0 && elide_empty_files)
        {
-         if (unlink (output_filename))
-           error (0, errno, "%s", output_filename);
-         files_created--;
+         sigset_t oldset;
+         bool unlink_ok;
+         int unlink_errno;
+
+         /* Remove the output file in a critical section, to avoid races.  */
+         sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
+         unlink_ok = (unlink (output_filename) == 0);
+         unlink_errno = errno;
+         files_created -= unlink_ok;
+         sigprocmask (SIG_SETMASK, &oldset, NULL);
+
+         if (! unlink_ok)
+           error (0, unlink_errno, "%s", output_filename);
        }
       else
        {
@@ -1273,9 +1311,6 @@ main (int argc, char **argv)
 {
   int optc;
   unsigned long int val;
-#ifdef SA_NOCLDSTOP
-  struct sigaction oldact, newact;
-#endif
 
   initialize_main (&argc, &argv);
   program_name = argv[0];
@@ -1295,37 +1330,6 @@ main (int argc, char **argv)
   /* Change the way xmalloc and xrealloc fail.  */
   xalloc_fail_func = cleanup;
 
-#ifdef SA_NOCLDSTOP
-  newact.sa_handler = interrupt_handler;
-  sigemptyset (&newact.sa_mask);
-  newact.sa_flags = 0;
-
-  sigaction (SIGHUP, NULL, &oldact);
-  if (oldact.sa_handler != SIG_IGN)
-    sigaction (SIGHUP, &newact, NULL);
-
-  sigaction (SIGINT, NULL, &oldact);
-  if (oldact.sa_handler != SIG_IGN)
-    sigaction (SIGINT, &newact, NULL);
-
-  sigaction (SIGQUIT, NULL, &oldact);
-  if (oldact.sa_handler != SIG_IGN)
-    sigaction (SIGQUIT, &newact, NULL);
-
-  sigaction (SIGTERM, NULL, &oldact);
-  if (oldact.sa_handler != SIG_IGN)
-    sigaction (SIGTERM, &newact, NULL);
-#else
-  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
-    signal (SIGHUP, interrupt_handler);
-  if (signal (SIGINT, SIG_IGN) != SIG_IGN)
-    signal (SIGINT, interrupt_handler);
-  if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
-    signal (SIGQUIT, interrupt_handler);
-  if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
-    signal (SIGTERM, interrupt_handler);
-#endif
-
   while ((optc = getopt_long (argc, argv, "f:b:kn:sqz", longopts, NULL)) != -1)
     switch (optc)
       {
@@ -1382,6 +1386,36 @@ main (int argc, char **argv)
   set_input_file (argv[optind++]);
 
   parse_patterns (argc, optind, argv);
+
+  {
+    int i;
+    static int const sig[] = { SIGHUP, SIGINT, SIGQUIT, SIGTERM };
+    enum { nsigs = sizeof sig / sizeof sig[0] };
+
+#ifdef SA_NOCLDSTOP
+    struct sigaction act;
+
+    sigemptyset (&caught_signals);
+    for (i = 0; i < nsigs; i++)
+      {
+       sigaction (sig[i], NULL, &act);
+       if (act.sa_handler != SIG_IGN)
+         sigaddset (&caught_signals, sig[i]);
+      }
+
+    act.sa_handler = interrupt_handler;
+    act.sa_mask = caught_signals;
+    act.sa_flags = 0;
+
+    for (i = 0; i < nsigs; i++)
+      if (sigismember (&caught_signals, sig[i]))
+       sigaction (sig[i], &act, NULL);
+#else
+    for (i = 0; i < nsigs; i++)
+      if (signal (sig[i], SIG_IGN) != SIG_IGN)
+       signal (sig[i], interrupt_handler);
+#endif
+  }
 
   split_file ();
 
Index: src/install.c
===================================================================
RCS file: /home/meyering/coreutils/cu/src/install.c,v
retrieving revision 1.158
diff -p -u -r1.158 install.c
--- src/install.c       7 Feb 2004 16:01:31 -0000       1.158
+++ src/install.c       15 Apr 2004 05:06:06 -0000
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <getopt.h>
 #include <sys/types.h>
+#include <signal.h>
 #include <pwd.h>
 #include <grp.h>
 
@@ -227,6 +228,10 @@ main (int argc, char **argv)
          break;
        case 's':
          strip_files = 1;
+#ifdef SIGCHLD
+         /* System V fork+wait does not work if SIGCHLD is ignored.  */
+         signal (SIGCHLD, SIG_DFL);
+#endif
          break;
        case 'd':
          dir_arg = 1;
Index: src/ls.c
===================================================================
RCS file: /home/meyering/coreutils/cu/src/ls.c,v
retrieving revision 1.352
diff -p -u -r1.352 ls.c
--- src/ls.c    2 Feb 2004 07:59:23 -0000       1.352
+++ src/ls.c    15 Apr 2004 16:38:57 -0000
@@ -973,33 +973,19 @@ restore_default_color (void)
 static void
 sighandler (int sig)
 {
+  /* SIGTSTP is special, since the application can receive that signal more
+     than once.  In this case, don't set the signal handler to the default.
+     Instead, just raise the uncatchable SIGSTOP.  */
 #ifndef SA_NOCLDSTOP
-  signal (sig, SIG_IGN);
+  signal (sig, sig == SIGTSTP ? sighandler : SIG_IGN);
 #endif
 
   restore_default_color ();
 
-  /* SIGTSTP is special, since the application can receive that signal more
-     than once.  In this case, don't set the signal handler to the default.
-     Instead, just raise the uncatchable SIGSTOP.  */
   if (sig == SIGTSTP)
-    {
-      sig = SIGSTOP;
-    }
+    sig = SIGSTOP;
   else
-    {
-#ifdef SA_NOCLDSTOP
-      struct sigaction sigact;
-
-      sigact.sa_handler = SIG_DFL;
-      sigemptyset (&sigact.sa_mask);
-      sigact.sa_flags = 0;
-      sigaction (sig, &sigact, NULL);
-#else
-      signal (sig, SIG_DFL);
-#endif
-    }
-
+    signal (sig, SIG_DFL);
   raise (sig);
 }
 
@@ -1043,34 +1029,35 @@ main (int argc, char **argv)
        check_symlink_color = 1;
 
       {
-       unsigned int j;
-       static int const sigs[] = { SIGHUP, SIGINT, SIGPIPE,
-                                   SIGQUIT, SIGTERM, SIGTSTP };
-       unsigned int nsigs = sizeof sigs / sizeof *sigs;
+       int j;
+       static int const sig[] = { SIGHUP, SIGINT, SIGPIPE,
+                                  SIGQUIT, SIGTERM, SIGTSTP };
+       enum { nsigs = sizeof sig / sizeof sig[0] };
+
 #ifdef SA_NOCLDSTOP
-       struct sigaction oldact, newact;
+       struct sigaction act;
        sigset_t caught_signals;
 
        sigemptyset (&caught_signals);
        for (j = 0; j < nsigs; j++)
-         sigaddset (&caught_signals, sigs[j]);
-       newact.sa_handler = sighandler;
-       newact.sa_mask = caught_signals;
-       newact.sa_flags = 0;
-#endif
+         {
+           sigaction (sig[j], NULL, &act);
+           if (act.sa_handler != SIG_IGN)
+             sigaddset (&caught_signals, sig[j]);
+         }
+
+       act.sa_handler = sighandler;
+       act.sa_mask = caught_signals;
+       act.sa_flags = SA_RESTART;
 
        for (j = 0; j < nsigs; j++)
-         {
-           int sig = sigs[j];
-#ifdef SA_NOCLDSTOP
-           sigaction (sig, NULL, &oldact);
-           if (oldact.sa_handler != SIG_IGN)
-             sigaction (sig, &newact, NULL);
+         if (sigismember (&caught_signals, sig[j]))
+           sigaction (sig[j], &act, NULL);
 #else
-           if (signal (sig, SIG_IGN) != SIG_IGN)
-             signal (sig, sighandler);
+       for (j = 0; j < nsigs; j++)
+         if (signal (sig[j], SIG_IGN) != SIG_IGN)
+           signal (sig[j], sighandler);
 #endif
-         }
       }
     }
 
Index: src/nohup.c
===================================================================
RCS file: /home/meyering/coreutils/cu/src/nohup.c,v
retrieving revision 1.13
diff -p -u -r1.13 nohup.c
--- src/nohup.c 4 Apr 2004 06:33:44 -0000       1.13
+++ src/nohup.c 15 Apr 2004 05:26:36 -0000
@@ -158,18 +158,7 @@ main (int argc, char **argv)
        error (NOHUP_FAILURE, errno, _("failed to redirect standard error"));
     }
 
-  /* Ignore hang-up signals.  */
-  {
-#ifdef _POSIX_SOURCE
-    struct sigaction sigact;
-    sigact.sa_handler = SIG_IGN;
-    sigemptyset (&sigact.sa_mask);
-    sigact.sa_flags = 0;
-    sigaction (SIGHUP, &sigact, NULL);
-#else
-    signal (SIGHUP, SIG_IGN);
-#endif
-  }
+  signal (SIGHUP, SIG_IGN);
 
   {
     int exit_status;
Index: src/shred.c
===================================================================
RCS file: /home/meyering/coreutils/cu/src/shred.c,v
retrieving revision 1.86
diff -p -u -r1.86 shred.c
--- src/shred.c 15 Apr 2004 10:50:07 -0000      1.86
+++ src/shred.c 19 Apr 2004 04:07:48 -0000
@@ -522,7 +522,7 @@ isaac_seed_finish (struct isaac_state *s
  * possibility of SIGILL while we're working.
  */
 static jmp_buf env;
-static RETSIGTYPE
+static void
 sigill_handler (int signum)
 {
   (void) signum;
@@ -539,7 +539,7 @@ sigill_handler (int signum)
 static void
 isaac_seed_machdep (struct isaac_state *s)
 {
-  RETSIGTYPE (*old_handler[2]) (int);
+  void (* volatile old_handler[2]) (int);
 
   /* This is how one does try/except in C */
   old_handler[0] = signal (SIGILL, sigill_handler);
Index: src/sort.c
===================================================================
RCS file: /home/meyering/coreutils/cu/src/sort.c,v
retrieving revision 1.281
diff -p -u -r1.281 sort.c
--- src/sort.c  17 Feb 2004 10:52:49 -0000      1.281
+++ src/sort.c  15 Apr 2004 16:39:12 -0000
@@ -2133,19 +2133,7 @@ sighandler (int sig)
 
   cleanup ();
 
-#ifdef SA_NOCLDSTOP
-  {
-    struct sigaction sigact;
-
-    sigact.sa_handler = SIG_DFL;
-    sigemptyset (&sigact.sa_mask);
-    sigact.sa_flags = 0;
-    sigaction (sig, &sigact, NULL);
-  }
-#else
   signal (sig, SIG_DFL);
-#endif
-
   raise (sig);
 }
 
@@ -2225,11 +2213,6 @@ main (int argc, char **argv)
                               : COMMON_SHORT_OPTIONS "y:");
   char *minus = "-", **files;
   char const *outfile = minus;
-  static int const sigs[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM };
-  unsigned int nsigs = sizeof sigs / sizeof *sigs;
-#ifdef SA_NOCLDSTOP
-  struct sigaction oldact, newact;
-#endif
 
   initialize_main (&argc, &argv);
   program_name = argv[0];
@@ -2269,32 +2252,34 @@ main (int argc, char **argv)
   have_read_stdin = false;
   inittables ();
 
-#ifdef SA_NOCLDSTOP
   {
-    unsigned int i;
+    int i;
+    static int const sig[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM };
+    enum { nsigs = sizeof sig / sizeof sig[0] };
+
+#ifdef SA_NOCLDSTOP
+    struct sigaction act;
+
     sigemptyset (&caught_signals);
     for (i = 0; i < nsigs; i++)
-      sigaddset (&caught_signals, sigs[i]);
-    newact.sa_handler = sighandler;
-    newact.sa_mask = caught_signals;
-    newact.sa_flags = 0;
-  }
-#endif
+      {
+       sigaction (sig[i], NULL, &act);
+       if (act.sa_handler != SIG_IGN)
+         sigaddset (&caught_signals, sig[i]);
+      }
+
+    act.sa_handler = sighandler;
+    act.sa_mask = caught_signals;
+    act.sa_flags = 0;
 
-  {
-    unsigned int i;
     for (i = 0; i < nsigs; i++)
-      {
-       int sig = sigs[i];
-#ifdef SA_NOCLDSTOP
-       sigaction (sig, NULL, &oldact);
-       if (oldact.sa_handler != SIG_IGN)
-         sigaction (sig, &newact, NULL);
+      if (sigismember (&caught_signals, sig[i]))
+       sigaction (sig[i], &act, NULL);
 #else
-       if (signal (sig, SIG_IGN) != SIG_IGN)
-         signal (sig, sighandler);
+    for (i = 0; i < nsigs; i++)
+      if (signal (sig[i], SIG_IGN) != SIG_IGN)
+       signal (sig[i], sighandler);
 #endif
-      }
   }
 
   gkey.sword = gkey.eword = SIZE_MAX;
Index: src/tee.c
===================================================================
RCS file: /home/meyering/coreutils/cu/src/tee.c,v
retrieving revision 1.71
diff -p -u -r1.71 tee.c
--- src/tee.c   21 Jan 2004 23:46:53 -0000      1.71
+++ src/tee.c   15 Apr 2004 05:16:02 -0000
@@ -115,33 +115,7 @@ main (int argc, char **argv)
     }
 
   if (ignore_interrupts)
-    {
-#ifdef _POSIX_SOURCE
-      struct sigaction sigact;
-
-      sigact.sa_handler = SIG_IGN;
-      sigemptyset (&sigact.sa_mask);
-      sigact.sa_flags = 0;
-      sigaction (SIGINT, &sigact, NULL);
-#else                          /* !_POSIX_SOURCE */
-      signal (SIGINT, SIG_IGN);
-#endif                         /* _POSIX_SOURCE */
-    }
-
-  /* Don't let us be killed if one of the output files is a pipe that
-     doesn't consume all its input.  */
-#ifdef _POSIX_SOURCE
-  {
-    struct sigaction sigact;
-
-    sigact.sa_handler = SIG_IGN;
-    sigemptyset (&sigact.sa_mask);
-    sigact.sa_flags = 0;
-    sigaction (SIGPIPE, &sigact, NULL);
-  }
-#else
-  signal (SIGPIPE, SIG_IGN);
-#endif
+    signal (SIGINT, SIG_IGN);
 
   /* Do *not* warn if tee is given no file arguments.
      POSIX requires that it work when given no arguments.  */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]