]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
env: add --list-signal-handling to output non default handling
authorPádraig Brady <P@draigBrady.com>
Mon, 4 Mar 2019 07:50:21 +0000 (23:50 -0800)
committerPádraig Brady <P@draigBrady.com>
Mon, 4 Mar 2019 08:37:42 +0000 (00:37 -0800)
* src/env.c (main): Output blocked or ignored signals
before a command is executed.
* doc/coreutils.texi (env invocation): Add the option.
* tests/misc/env-signal-handler.sh: Add a test case.
* NEWS: Mention the new feature.

NEWS
doc/coreutils.texi
src/env.c
tests/misc/env-signal-handler.sh

diff --git a/NEWS b/NEWS
index aa6ed0c90e2ac36f73fdfe6042a066809b14c13b..dd1b9bb63e15982db39af0e6d5addff6beb875aa 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -87,6 +87,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   env now supports '--default-signal[=SIG]', '--ignore-signal[=SIG]', and
   '--block-signal[=SIG], to setup signal handling before executing a program.
 
+  env now supports '--list-signal-handling' to indicate non-default
+  signal handling before executing a program.
+
 ** New commands
 
   basenc is added to complement existing base64,base32 commands,
index 7ca47d04df60f93f637d130b1ee9671370b9f9f5..097f04ca3067c4a7097729c17c6475fd745b274e 100644 (file)
@@ -17304,6 +17304,9 @@ env --default-signal=INT,PIPE --ignore-signal=INT
 @item --block-signal[=@var{sig}]
 Block signal(s) @var{sig} from being delivered.
 
+@item --list-signal-handling
+List blocked or ignored signals to stderr, before executing a command.
+
 @item -v
 @itemx --debug
 @opindex -v
index 70c703d04807a9a0fbce6f864545e63fe14fd660..5adc7d9eb2bf2430866ed679362636c70536561d 100644 (file)
--- 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:iS:u:v0 \t";
 
 /* For long options that have no equivalent short option, use a
@@ -79,6 +82,7 @@ enum
   DEFAULT_SIGNAL_OPTION = CHAR_MAX + 1,
   IGNORE_SIGNAL_OPTION,
   BLOCK_SIGNAL_OPTION,
+  LIST_SIGNAL_HANDLING_OPTION,
 };
 
 static struct option const longopts[] =
@@ -90,6 +94,7 @@ static struct option const longopts[] =
   {"default-signal", optional_argument, NULL, DEFAULT_SIGNAL_OPTION},
   {"ignore-signal",  optional_argument, NULL, IGNORE_SIGNAL_OPTION},
   {"block-signal",   optional_argument, NULL, BLOCK_SIGNAL_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},
@@ -133,6 +138,9 @@ Set each NAME to VALUE in the environment and run COMMAND.\n\
 "), stdout);
       fputs (_("\
       --ignore-signal[=SIG]   set handling of SIG signals(s) to do nothing\n\
+"), stdout);
+      fputs (_("\
+      --list-signal-handling  list non default signal handling to stderr\n\
 "), stdout);
       fputs (_("\
   -v, --debug          print verbose information for each processing step\n\
@@ -746,6 +754,35 @@ set_signal_proc_mask (void)
     die (EXIT_CANCELED, errno, _("failed to set signal process mask"));
 }
 
+static void
+list_signal_handling (void)
+{
+  sigset_t set;
+  char signame[SIG2STR_MAX];
+
+  sigemptyset (&set);
+  if (sigprocmask (0, NULL, &set))
+    die (EXIT_CANCELED, errno, _("failed to get signal process mask"));
+
+  for (int i = 1; i <= SIGNUM_BOUND; i++)
+    {
+      struct sigaction act;
+      if (sigaction (i, NULL, &act))
+        continue;
+
+      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);
+      fprintf (stderr, "%-10s (%2d): %s%s%s\n", signame, i,
+               blocked, connect, ignored);
+    }
+}
+
 int
 main (int argc, char **argv)
 {
@@ -789,6 +826,9 @@ main (int argc, char **argv)
         case BLOCK_SIGNAL_OPTION:
           parse_block_signal_params (optarg, true);
           break;
+        case LIST_SIGNAL_HANDLING_OPTION:
+          report_signal_handling = true;
+          break;
         case 'C':
           newdir = optarg;
           break;
@@ -868,6 +908,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));
index fb8ada9b157da8ca05a3d35bf56a1ce78092cc8f..755d95372da568b57ceccb77d7eccfb1d1289d59 100755 (executable)
@@ -17,7 +17,7 @@
 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
-print_ver_ env seq test timeout
+print_ver_ env seq test timeout printf
 trap_sigpipe_or_skip_
 
 # Paraphrasing http://bugs.gnu.org/34488#8:
@@ -128,4 +128,12 @@ sed -n '1,2p' err7t > err7 || framework_failure_
 compare exp-err6 err7 || fail=1
 
 
+# env test --list-signal-handling
+env --default-signal --ignore-signal=INT --list-signal-handling true \
+  2> err8t || fail=1
+sed 's/(.*)/()/' err8t > err8 || framework_failure_
+env printf 'INT        (): IGNORE\n' > exp-err8
+compare exp-err8 err8 || fail=1
+
+
 Exit $fail