Add ability to ignore signals
This commit is contained in:
parent
859cfa61de
commit
1a7c635071
4 changed files with 34 additions and 6 deletions
|
@ -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
|
||||
|
||||
|
|
18
dumb-init.c
18
dumb-init.c
|
@ -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);
|
||||
kill(use_setsid ? -child_pid : child_pid, signum);
|
||||
DEBUG("Forwarded signal %d to children.\n", 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Reference in a new issue