>From 150c30aec340d6ce00afa1251e6962c012449407 Mon Sep 17 00:00:00 2001 From: Assaf Gordon Date: Mon, 25 Feb 2019 18:03:19 -0700 Subject: [PATCH 3/3] env: add --list-blocked-signals/--list-signal-actions options Example: $ ( trap '' PIPE && env --list-signal-actions ) PIPE (13): ignore * NEWS: Mention new options. * doc/coreutils.texi (env invocation): Mention new options. * src/env.c (longopts,usage): Add new options. (list_signal_actions, list_blocked_signals): New functions. (main): Handle new options. --- NEWS | 3 +++ doc/coreutils.texi | 8 ++++++ src/env.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index cb8aa107f..3cef6066e 100644 --- a/NEWS +++ b/NEWS @@ -87,6 +87,9 @@ GNU coreutils NEWS -*- outline -*- env now supports '--{block,unblock,setmask}-singal[=SIG]' to block/unblock signal delivery before executing a program. + env now supports '--list-signal-actions' and '--list-blocked-signals' + options. + ** New commands basenc is added to complement existing base64,base32 commands, diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 8f5212a72..b63161803 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -17309,6 +17309,14 @@ Unblock signal @var{sig}. Set list of blocked signals to @var{sig}. All other signals will be unblocked. address@hidden --list-signal-actions +List non-default actions for all signals and exit. +If all signals are set to their default action, nothing is printed. + address@hidden --list-blocked-signals +List blocked (masked) signals and exit. +If no signals are blocked, nothing is printed. + @item -p Equivalent to @option{--default-signal=PIPE} - sets SIGPIPE to its default diff --git a/src/env.c b/src/env.c index 4cae7d47f..43856200f 100644 --- a/src/env.c +++ b/src/env.c @@ -78,7 +78,9 @@ enum IGNORE_SIGNAL_OPTION, BLOCK_SIGNAL_OPTION, UNBLOCK_SIGNAL_OPTION, - SETMASK_SIGNAL_OPTION + SETMASK_SIGNAL_OPTION, + LIST_SIGNAL_ACTIONS_OPTION, + LIST_BLOCKED_SIGNALS_OPTION, }; static struct option const longopts[] = @@ -89,9 +91,11 @@ static struct option const longopts[] = {"chdir", required_argument, NULL, 'C'}, {"default-signal", optional_argument, NULL, DEFAULT_SIGNAL_OPTION}, {"ignore-signal", optional_argument, NULL, IGNORE_SIGNAL_OPTION}, + {"list-signal-actions", no_argument, NULL, LIST_SIGNAL_ACTIONS_OPTION}, {"block-signal", optional_argument, NULL, BLOCK_SIGNAL_OPTION}, {"unblock-signal", optional_argument, NULL, UNBLOCK_SIGNAL_OPTION}, {"setmask-signal", optional_argument, NULL, SETMASK_SIGNAL_OPTION}, + {"list-blocked-signals", no_argument, NULL, LIST_BLOCKED_SIGNALS_OPTION}, {"debug", no_argument, NULL, 'v'}, {"split-string", required_argument, NULL, 'S'}, {GETOPT_HELP_OPTION_DECL}, @@ -143,6 +147,15 @@ Set each NAME to VALUE in the environment and run COMMAND.\n\ used to pass multiple arguments on shebang lines\n\ "), stdout); fputs (_("\ + --list-signal-actions list non-default actions for signals and exit.\n\ + if all signals use their default actions,\n\ + nothing is printed.\n\ +"), stdout); + fputs (_("\ + --list-blocked-signals list blocked (masked) signals and exit.\n\ + if no signals are blocked, nothing is printed.\n\ +"), stdout); + fputs (_("\ -p same as --default-signal=PIPE\n\ "), stdout); fputs (_("\ @@ -670,6 +683,35 @@ reset_signal_handlers (void) } static void +list_signal_actions (void) +{ + char signame[SIG2STR_MAX]; + const char* action; + + for (int i = 1; i < SIGNUM_BOUND; i++) + { + struct sigaction act; + if (sigaction (i, NULL, &act)) + continue; + + if (act.sa_flags & SA_SIGINFO) + action = "sig-action"; + else if (act.sa_handler == SIG_DFL) + continue; /* no need to print defaults. */ + else if (act.sa_handler == SIG_IGN) + action = "ignore"; + else + action = "sig-handler"; + + sig2str (i, signame); + printf ("%-10s (%2d): %s\n", signame, i, action); + } + + exit (EXIT_SUCCESS); +} + + +static void parse_block_signal_params (const char* optarg, bool block) { char signame[SIG2STR_MAX]; @@ -747,6 +789,29 @@ set_signal_proc_mask (void) die (EXIT_CANCELED, errno, _("failed to set signal process mask")); } +static void +list_blocked_signals (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++) + { + if (!sigismember (&set, i)) + continue; + + sig2str (i, signame); + printf ("%-10s (%2d)\n", signame, i); + } + + exit (EXIT_SUCCESS); +} + + int main (int argc, char **argv) { @@ -790,6 +855,9 @@ main (int argc, char **argv) case IGNORE_SIGNAL_OPTION: parse_signal_action_params (optarg, false); break; + case LIST_SIGNAL_ACTIONS_OPTION: + list_signal_actions (); + break; case BLOCK_SIGNAL_OPTION: parse_block_signal_params (optarg, true); break; @@ -801,6 +869,9 @@ main (int argc, char **argv) sigemptyset (&block_signals); parse_block_signal_params (optarg, true); break; + case LIST_BLOCKED_SIGNALS_OPTION: + list_blocked_signals (); + break; case 'C': newdir = optarg; break; -- 2.11.0