Subject: Re: bug#34488: Add sort --limit, or document workarounds for sort|head error messages

From: Pádraig Brady <[email-masked]>
Date: Sat, 23 Feb 2019 22:13:41 -0800

On 18/02/19 01:46, Assaf Gordon wrote:
> Hello,
> 
> Thanks for all comments (on and off list).
> Attached an updated patch with documentation.
> 
> The supported options are:
> 
>   --default-signal[=SIG]  reset signal SIG to its default signal handler.
>                           without SIG, all known signals are included.
>                           multiple signals can be comma-separated.
>   --ignore-signal[=SIG]   set signal SIG to be IGNORED.
>                           without SIG, all known signals are included.
>                           multiple signals can be comma-separated.
>   -p                      same as --default-signal=PIPE
> 
> (lower-case "-p" as to not conflict with BSD, but of course can be
> changed to another letter).
> 
> The new 'env-signal-handler.sh' test passes on GNU/linux, non-gnu/linux
> (alpine), and Free/Open/Net BSD.
> 
> Comments very welcomed,

Attached is a patch to be squashed in to:

  Process the same signals as kill -l
  Output whether action failed or not
  Don't run sigaction(..set..) if get failed

I'm not that enthusiastic about the -p
since it treats PIPE specially here,
and it's not special from env's point of view.

cheers,
Pádraig
>From 9d873110e29a6f6fb5c4932164e8ce5ad6ad0668 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email-masked]>
Date: Sat, 23 Feb 2019 22:11:08 -0800
Subject: [PATCH] env: --default fixes

Process the same signals as kill -l
Output whether action failed or not
Don't run sigaction(..set..) if get failed
---
 src/env.c | 48 +++++++++++++++++++++++++++---------------------
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/src/env.c b/src/env.c
index 6c20ac4..a601538 100644
--- a/src/env.c
+++ b/src/env.c
@@ -572,13 +572,13 @@ parse_signal_params (const char* optarg, bool set_default)
   char *opt_sig;
   char *optarg_writable;
 
-  if (!optarg)
+  if (! optarg)
     {
       /* without an argument, reset all signals.
          Some signals cannot be set to ignore or default (e.g., SIGKILL,
          SIGSTOP on most OSes, and SIGCONT on AIX.) - so ignore errors.  */
       for (int i = 0 ; i < SIGNUM_BOUND; ++i)
-        if (sig2str (i, signame) == 0)
+        if (sig2str (i + 1, signame) == 0)
           signals[i] = set_default ? DEFAULT_NOERR : IGNORE_NOERR;
       return;
     }
@@ -603,38 +603,44 @@ parse_signal_params (const char* optarg, bool set_default)
 static void
 reset_signal_handlers (void)
 {
-  for (int i=0; i<SIGNUM_BOUND; ++i)
+  for (int i = 0; i < SIGNUM_BOUND; i++)
     {
+      int sig = i + 1;
       struct sigaction act;
 
       if (signals[i] == UNCHANGED)
         continue;
 
-      bool ignore_errors = (signals[i] == DEFAULT_NOERR \
+      bool ignore_errors = (signals[i] == DEFAULT_NOERR
                             || signals[i] == IGNORE_NOERR);
 
-      bool set_to_default = (signals[i] == DEFAULT \
-                            || signals[i] == DEFAULT_NOERR);
+      bool set_to_default = (signals[i] == DEFAULT
+                             || signals[i] == DEFAULT_NOERR);
+
+      int sig_err = sigaction (sig, NULL, &act);
+
+      if (sig_err && !ignore_errors)
+        die (EXIT_CANCELED, errno,
+             _("failed to get signal action for signal %d"), sig);
+
+      if (! sig_err)
+        {
+          act.sa_handler = set_to_default ? SIG_DFL : SIG_IGN;
+
+          if ((sig_err = sigaction (sig, &act, NULL)) && !ignore_errors)
+            die (EXIT_CANCELED, errno,
+                 _("failed to set signal action for signal %d"), sig);
+        }
 
       if (dev_debug)
         {
           char signame[SIG2STR_MAX];
-          sig2str (i, signame);
-          devmsg ("Resetting signal %s (%d) to %s%s\n",
-                  signame, i,
-                  set_to_default?"DEFAULT":"IGNORE",
-                  ignore_errors?" (ignoring errors)":"");
+          sig2str (sig, signame);
+          devmsg ("Reset signal %s (%d) to %s%s\n",
+                  signame, sig,
+                  set_to_default ? "DEFAULT" : "IGNORE",
+                  sig_err ? " (failure ignored)" : "");
         }
-
-        if (sigaction (i, NULL, &act) && !ignore_errors)
-          die (EXIT_CANCELED, errno,
-               _("failed to get signal action for signal %d"), i);
-
-        act.sa_handler = set_to_default ? SIG_DFL : SIG_IGN;
-
-        if (sigaction (i, &act, NULL) && !ignore_errors)
-          die (EXIT_CANCELED, errno,
-               _("failed to set signal action for signal %d"), i);
     }
 }
 
-- 
2.9.3