Add ability to ignore signals

This commit is contained in:
Chris Kuehl 2016-06-14 11:34:52 -07:00
parent 859cfa61de
commit 1a7c635071
4 changed files with 34 additions and 6 deletions

View file

@ -116,6 +116,8 @@ different stop signal in order to do graceful cleanup.
For example, to rewrite the signal SIGTERM (number 15) to SIGQUIT (number 3), For example, to rewrite the signal SIGTERM (number 15) to SIGQUIT (number 3),
just add `--rewrite 15:3` on the command line. just add `--rewrite 15:3` on the command line.
To drop a signal entirely, you can rewrite it to the special number `0`.
#### Signal rewriting special case #### Signal rewriting special case

View file

@ -35,7 +35,7 @@
#define MAXSIG 31 #define MAXSIG 31
// Indices are one-indexed (signal 1 is at index 1). Index zero is unused. // Indices are one-indexed (signal 1 is at index 1). Index zero is unused.
int signal_rewrite[MAXSIG + 1] = {0}; int signal_rewrite[MAXSIG + 1] = {[0 ... MAXSIG] = -1};
pid_t child_pid = -1; pid_t child_pid = -1;
char debug = 0; char debug = 0;
@ -46,14 +46,18 @@ int translate_signal(int signum) {
return signum; return signum;
} else { } else {
int translated = signal_rewrite[signum]; int translated = signal_rewrite[signum];
return translated == 0 ? signum : translated; return translated == -1 ? signum : translated;
} }
} }
void forward_signal(int signum) { void forward_signal(int signum) {
signum = translate_signal(signum); signum = translate_signal(signum);
if (signum != -1) {
kill(use_setsid ? -child_pid : child_pid, signum); kill(use_setsid ? -child_pid : child_pid, signum);
DEBUG("Forwarded signal %d to children.\n", signum); DEBUG("Forwarded signal %d to children.\n", signum);
} else {
DEBUG("Not forwarding signal %d to children (ignored).\n", signum);
}
} }
/* /*
@ -119,6 +123,8 @@ void print_help(char *argv[]) {
" In this mode, signals are only proxied to the\n" " In this mode, signals are only proxied to the\n"
" direct child and not any of its descendants.\n" " direct child and not any of its descendants.\n"
" -r, --rewrite s:r Rewrite received signal s to new signal r before proxying.\n" " -r, --rewrite s:r Rewrite received signal s to new signal r before proxying.\n"
" To ignore (not proxy) a signal, rewrite it to 0.\n"
" This option can be specified multiple times.\n"
" -v, --verbose Print debugging information to stderr.\n" " -v, --verbose Print debugging information to stderr.\n"
" -h, --help Print this help message and exit.\n" " -h, --help Print this help message and exit.\n"
" -V, --version Print the current version and exit.\n" " -V, --version Print the current version and exit.\n"
@ -146,7 +152,7 @@ void parse_rewrite_signum(char *arg) {
if ( if (
sscanf(arg, "%d:%d", &signum, &replacement) == 2 && sscanf(arg, "%d:%d", &signum, &replacement) == 2 &&
(signum >= 1 && signum <= MAXSIG) && (signum >= 1 && signum <= MAXSIG) &&
(replacement >= 1 && replacement <= MAXSIG) (replacement >= 0 && replacement <= MAXSIG)
) { ) {
signal_rewrite[signum] = replacement; signal_rewrite[signum] = replacement;
} else { } else {
@ -155,7 +161,7 @@ void parse_rewrite_signum(char *arg) {
} }
void set_rewrite_to_sigstop_if_not_defined(int signum) { void set_rewrite_to_sigstop_if_not_defined(int signum) {
if (signal_rewrite[signum] == 0) if (signal_rewrite[signum] == -1)
signal_rewrite[signum] = SIGSTOP; signal_rewrite[signum] = SIGSTOP;
} }

View file

@ -41,6 +41,8 @@ def test_help_message(flag, both_debug_modes, both_setsid_modes, current_version
b' In this mode, signals are only proxied to the\n' b' In this mode, signals are only proxied to the\n'
b' direct child and not any of its descendants.\n' b' direct child and not any of its descendants.\n'
b' -r, --rewrite s:r Rewrite received signal s to new signal r before proxying.\n' b' -r, --rewrite s:r Rewrite received signal s to new signal r before proxying.\n'
b' To ignore (not proxy) a signal, rewrite it to 0.\n'
b' This option can be specified multiple times.\n'
b' -v, --verbose Print debugging information to stderr.\n' b' -v, --verbose Print debugging information to stderr.\n'
b' -h, --help Print this help message and exit.\n' b' -h, --help Print this help message and exit.\n'
b' -V, --version Print the current version and exit.\n' b' -V, --version Print the current version and exit.\n'

View file

@ -109,3 +109,21 @@ def test_default_rewrites_can_be_overriden_with_setsid_enabled():
proc.send_signal(signal.SIGCONT) proc.send_signal(signal.SIGCONT)
assert proc.stdout.readline() == '{0}\n'.format(signal.SIGCONT).encode('ascii') assert proc.stdout.readline() == '{0}\n'.format(signal.SIGCONT).encode('ascii')
assert process_state(proc.pid) in ['running', 'sleeping'] assert process_state(proc.pid) in ['running', 'sleeping']
@pytest.mark.usefixtures('both_debug_modes', 'both_setsid_modes')
def test_ignored_signals_are_not_proxied():
"""Ensure dumb-init can ignore signals."""
rewrite_map = {
signal.SIGTERM: signal.SIGQUIT,
signal.SIGINT: 0,
signal.SIGWINCH: 0,
}
with _print_signals(_rewrite_map_to_args(rewrite_map)) as proc:
proc.send_signal(signal.SIGTERM)
proc.send_signal(signal.SIGINT)
assert proc.stdout.readline() == '{0}\n'.format(signal.SIGQUIT).encode('ascii')
proc.send_signal(signal.SIGWINCH)
proc.send_signal(signal.SIGHUP)
assert proc.stdout.readline() == '{0}\n'.format(signal.SIGHUP).encode('ascii')