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

From: Pádraig Brady <[email-masked]>
Date: Sun, 3 Mar 2019 16:59:28 -0800

On 03/03/19 16:07, Pádraig Brady wrote:
> On 03/03/19 15:36, Pádraig Brady wrote:
>> On 25/02/19 22:35, Pádraig Brady wrote:
>>> Thanks for doing all that.
>>> I've attached a few changes:
>>>
>>> - spelling fixes
>>> - usage() clarified/reordered
>>> - ensure sigset_t are initialized
>>> - Don't setprocmask() unless specified
>>> - Simplified SETMASK_SIGNAL_OPTION handling
>>> - The test missed `env` as a prerequisite
>>> - The test was slow/spun cpu, so used sleep instead of seq
>>> - Used $SHELL in case sh didn't support trap
>>>
>>> I see that the last signal that `kill -l` lists is not included.
>>> I think we should be processing SIGNUM_BOUND also?
>>
>> An additional patch attached to replace --list-signal-actions
>> with --list-ignored-signals.  This is simpler, and more symmetric
>> with the other options. Also the extra output was moot I think
>> since handlers are reset upon exec
> 
> I've locally adjusted the NEWS/texi for that patch also.
> I've a local patch to include SIGNUM_BOUND which I won't spam the list with.
> 
> Attached is a patch to remove the -p and --set-mask options,
> which I've a light preference for.
> I'll think some more about it.

Attached is a patch to combine the two --list options
to a single --list-signal-handling option.
This also doesn't exit, and so is more useful as
users can add --list-signal to their env commands
to diagnose signal handling.  One can easily use `true`
as the command to get the original list only functionality.

A summary of the all signal options in my local set now is:

  --block-signal[=SIG]    block delivery of SIG signal(s) to COMMAND
  --unblock-signal[=SIG]  unblock delivery of SIG signal(s) to COMMAND
  --default-signal[=SIG]  reset handling of SIG signal(s) to the default
  --ignore-signal[=SIG]   set handling of SIG signals(s) to do nothing
  --list-signal-handling  list non default signal handling to stderr

cheers,
Pádraig
From 715254df092d6e3dfac7bdfd72f7307dce21dabd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email-masked]>
Date: Sun, 3 Mar 2019 16:50:27 -0800
Subject: [PATCH] env: add only a single --list-signal-handling option

This also doesn't exit, which is more useful as
it directly confirms any inherited handling
in combination with any signal settings we may have set.
One can easily use `true` as the command to get
the original list only functionality
---
 NEWS               |  3 ++-
 doc/coreutils.texi |  5 ++---
 src/env.c          | 54 +++++++++++++++++++-----------------------------------
 3 files changed, 23 insertions(+), 39 deletions(-)

diff --git a/NEWS b/NEWS
index 33f1ef2..6fbc8f1 100644
--- a/NEWS
+++ b/NEWS
@@ -90,7 +90,8 @@ GNU coreutils NEWS                                    -*- outline -*-
   env now supports '--{block,unblock,setmask}-signal[=SIG]' to block/unblock
   signal delivery before executing a program.
 
-  env now supports '--list-blocked-signals', and '--list-ignored-signals'.
+  env now supports '--list-signal-handling' to identify signal handling
+  before executing a program.
 
 ** New commands
 
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 3c220ea..0e4ed16 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -17309,9 +17309,8 @@ Unblock signal(s) @var{sig}.
 List blocked (masked) signals and exit.
 If no signals are blocked, nothing is printed.
 
-@item --list-ignored-signals
-List ignored signals and exit.
-If no signals are ignored, nothing is printed.
+@item --list-signal-handling
+List blocked or ignored signals to stderr, before executing a command.
 
 @item -v
 @itemx --debug
diff --git a/src/env.c b/src/env.c
index 7bc3c7b..9a910da 100644
--- a/src/env.c
+++ b/src/env.c
@@ -70,6 +70,9 @@ static sigset_t unblock_signals;
 /* Whether signal mask adjustment requested.  */
 static bool sig_mask_changed;
 
+/* Whether to list non default handling.  */
+static bool report_signal_handling;
+
 static char const shortopts[] = "+C:ipS:u:v0 \t";
 
 /* For long options that have no equivalent short option, use a
@@ -80,8 +83,7 @@ enum
   IGNORE_SIGNAL_OPTION,
   BLOCK_SIGNAL_OPTION,
   UNBLOCK_SIGNAL_OPTION,
-  LIST_BLOCKED_SIGNALS_OPTION,
-  LIST_IGNORED_SIGNALS_OPTION,
+  LIST_SIGNAL_HANDLING_OPTION,
 };
 
 static struct option const longopts[] =
@@ -94,8 +96,7 @@ static struct option const longopts[] =
   {"ignore-signal",  optional_argument, NULL, IGNORE_SIGNAL_OPTION},
   {"block-signal",   optional_argument, NULL, BLOCK_SIGNAL_OPTION},
   {"unblock-signal", optional_argument, NULL, UNBLOCK_SIGNAL_OPTION},
-  {"list-blocked-signals", no_argument, NULL, LIST_BLOCKED_SIGNALS_OPTION},
-  {"list-ignored-signals", no_argument, NULL,  LIST_IGNORED_SIGNALS_OPTION},
+  {"list-signal-handling", no_argument, NULL,  LIST_SIGNAL_HANDLING_OPTION},
   {"debug", no_argument, NULL, 'v'},
   {"split-string", required_argument, NULL, 'S'},
   {GETOPT_HELP_OPTION_DECL},
@@ -144,10 +145,7 @@ Set each NAME to VALUE in the environment and run COMMAND.\n\
       --ignore-signal[=SIG]   set handling of SIG signals(s) to do nothing\n\
 "), stdout);
       fputs (_("\
-      --list-ignored-signals  list ignored signals and exit\n\
-"), stdout);
-      fputs (_("\
-      --list-blocked-signals  list blocked (masked) signals and exit\n\
+      --list-signal-handling  list non default signal handling to stderr\n\
 "), stdout);
       fputs (_("\
   -v, --debug          print verbose information for each processing step\n\
@@ -762,7 +760,7 @@ set_signal_proc_mask (void)
 }
 
 static void
-list_blocked_signals (void)
+list_signal_handling (void)
 {
   sigset_t set;
   char signame[SIG2STR_MAX];
@@ -773,35 +771,21 @@ list_blocked_signals (void)
 
   for (int i = 1; i <= SIGNUM_BOUND; i++)
     {
-      if (!sigismember (&set, i))
-        continue;
-
-      sig2str (i, signame);
-      printf ("%-10s (%2d)\n", signame, i);
-    }
-
-  exit (EXIT_SUCCESS);
-}
-
-static void
-list_ignored_signals (void)
-{
-  char signame[SIG2STR_MAX];
-
-  for (int i = 1; i <= SIGNUM_BOUND; i++)
-    {
       struct sigaction act;
       if (sigaction (i, NULL, &act))
         continue;
 
-      if (act.sa_handler != SIG_IGN)
+      char const* ignored = act.sa_handler == SIG_IGN ? "IGNORE" : "";
+      char const* blocked = sigismember (&set, i) ? "BLOCK" : "";
+      char const* connect = *ignored && *blocked ? "," : "";
+
+      if (! *ignored && ! *blocked)
         continue;
 
       sig2str (i, signame);
-      printf ("%-10s (%2d)\n", signame, i);
+      fprintf (stderr, "%-10s (%2d): %s%s%s\n", signame, i,
+               blocked, connect, ignored);
     }
-
-  exit (EXIT_SUCCESS);
 }
 
 int
@@ -849,11 +833,8 @@ main (int argc, char **argv)
         case UNBLOCK_SIGNAL_OPTION:
           parse_block_signal_params (optarg, false);
           break;
-        case LIST_BLOCKED_SIGNALS_OPTION:
-          list_blocked_signals ();
-          break;
-        case LIST_IGNORED_SIGNALS_OPTION:
-          list_ignored_signals ();
+        case LIST_SIGNAL_HANDLING_OPTION:
+          report_signal_handling = true;
           break;
         case 'C':
           newdir = optarg;
@@ -934,6 +915,9 @@ main (int argc, char **argv)
   if (sig_mask_changed)
     set_signal_proc_mask ();
 
+  if (report_signal_handling)
+    list_signal_handling ();
+
   if (newdir)
     {
       devmsg ("chdir:    %s\n", quoteaf (newdir));
-- 
2.9.3