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),
|
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
|
||||||
|
|
||||||
|
|
14
dumb-init.c
14
dumb-init.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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')
|
||||||
|
|
Loading…
Reference in a new issue