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),
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

View file

@ -35,7 +35,7 @@
#define MAXSIG 31
// 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;
char debug = 0;
@ -46,14 +46,18 @@ int translate_signal(int signum) {
return signum;
} else {
int translated = signal_rewrite[signum];
return translated == 0 ? signum : translated;
return translated == -1 ? signum : translated;
}
}
void forward_signal(int signum) {
signum = translate_signal(signum);
if (signum != -1) {
kill(use_setsid ? -child_pid : child_pid, 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"
" direct child and not any of its descendants.\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"
" -h, --help Print this help message and exit.\n"
" -V, --version Print the current version and exit.\n"
@ -146,7 +152,7 @@ void parse_rewrite_signum(char *arg) {
if (
sscanf(arg, "%d:%d", &signum, &replacement) == 2 &&
(signum >= 1 && signum <= MAXSIG) &&
(replacement >= 1 && replacement <= MAXSIG)
(replacement >= 0 && replacement <= MAXSIG)
) {
signal_rewrite[signum] = replacement;
} else {
@ -155,7 +161,7 @@ void parse_rewrite_signum(char *arg) {
}
void set_rewrite_to_sigstop_if_not_defined(int signum) {
if (signal_rewrite[signum] == 0)
if (signal_rewrite[signum] == -1)
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' 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' 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' -h, --help Print this help message 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)
assert proc.stdout.readline() == '{0}\n'.format(signal.SIGCONT).encode('ascii')
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')