Skip to content

Commit 2d5483d

Browse files
authored
Merge pull request #86 from chriskuehl/add-signal-ignoring
Add ability to ignore (not proxy) signals
2 parents 859cfa6 + 1a7c635 commit 2d5483d

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ different stop signal in order to do graceful cleanup.
116116
For example, to rewrite the signal SIGTERM (number 15) to SIGQUIT (number 3),
117117
just add `--rewrite 15:3` on the command line.
118118

119+
To drop a signal entirely, you can rewrite it to the special number `0`.
120+
119121

120122
#### Signal rewriting special case
121123

dumb-init.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
#define MAXSIG 31
3636

3737
// Indices are one-indexed (signal 1 is at index 1). Index zero is unused.
38-
int signal_rewrite[MAXSIG + 1] = {0};
38+
int signal_rewrite[MAXSIG + 1] = {[0 ... MAXSIG] = -1};
3939

4040
pid_t child_pid = -1;
4141
char debug = 0;
@@ -46,14 +46,18 @@ int translate_signal(int signum) {
4646
return signum;
4747
} else {
4848
int translated = signal_rewrite[signum];
49-
return translated == 0 ? signum : translated;
49+
return translated == -1 ? signum : translated;
5050
}
5151
}
5252

5353
void forward_signal(int signum) {
5454
signum = translate_signal(signum);
55-
kill(use_setsid ? -child_pid : child_pid, signum);
56-
DEBUG("Forwarded signal %d to children.\n", signum);
55+
if (signum != -1) {
56+
kill(use_setsid ? -child_pid : child_pid, signum);
57+
DEBUG("Forwarded signal %d to children.\n", signum);
58+
} else {
59+
DEBUG("Not forwarding signal %d to children (ignored).\n", signum);
60+
}
5761
}
5862

5963
/*
@@ -119,6 +123,8 @@ void print_help(char *argv[]) {
119123
" In this mode, signals are only proxied to the\n"
120124
" direct child and not any of its descendants.\n"
121125
" -r, --rewrite s:r Rewrite received signal s to new signal r before proxying.\n"
126+
" To ignore (not proxy) a signal, rewrite it to 0.\n"
127+
" This option can be specified multiple times.\n"
122128
" -v, --verbose Print debugging information to stderr.\n"
123129
" -h, --help Print this help message and exit.\n"
124130
" -V, --version Print the current version and exit.\n"
@@ -146,7 +152,7 @@ void parse_rewrite_signum(char *arg) {
146152
if (
147153
sscanf(arg, "%d:%d", &signum, &replacement) == 2 &&
148154
(signum >= 1 && signum <= MAXSIG) &&
149-
(replacement >= 1 && replacement <= MAXSIG)
155+
(replacement >= 0 && replacement <= MAXSIG)
150156
) {
151157
signal_rewrite[signum] = replacement;
152158
} else {
@@ -155,7 +161,7 @@ void parse_rewrite_signum(char *arg) {
155161
}
156162

157163
void set_rewrite_to_sigstop_if_not_defined(int signum) {
158-
if (signal_rewrite[signum] == 0)
164+
if (signal_rewrite[signum] == -1)
159165
signal_rewrite[signum] = SIGSTOP;
160166
}
161167

tests/cli_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ def test_help_message(flag, both_debug_modes, both_setsid_modes, current_version
4141
b' In this mode, signals are only proxied to the\n'
4242
b' direct child and not any of its descendants.\n'
4343
b' -r, --rewrite s:r Rewrite received signal s to new signal r before proxying.\n'
44+
b' To ignore (not proxy) a signal, rewrite it to 0.\n'
45+
b' This option can be specified multiple times.\n'
4446
b' -v, --verbose Print debugging information to stderr.\n'
4547
b' -h, --help Print this help message and exit.\n'
4648
b' -V, --version Print the current version and exit.\n'

tests/proxies_signals_test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,21 @@ def test_default_rewrites_can_be_overriden_with_setsid_enabled():
109109
proc.send_signal(signal.SIGCONT)
110110
assert proc.stdout.readline() == '{0}\n'.format(signal.SIGCONT).encode('ascii')
111111
assert process_state(proc.pid) in ['running', 'sleeping']
112+
113+
114+
@pytest.mark.usefixtures('both_debug_modes', 'both_setsid_modes')
115+
def test_ignored_signals_are_not_proxied():
116+
"""Ensure dumb-init can ignore signals."""
117+
rewrite_map = {
118+
signal.SIGTERM: signal.SIGQUIT,
119+
signal.SIGINT: 0,
120+
signal.SIGWINCH: 0,
121+
}
122+
with _print_signals(_rewrite_map_to_args(rewrite_map)) as proc:
123+
proc.send_signal(signal.SIGTERM)
124+
proc.send_signal(signal.SIGINT)
125+
assert proc.stdout.readline() == '{0}\n'.format(signal.SIGQUIT).encode('ascii')
126+
127+
proc.send_signal(signal.SIGWINCH)
128+
proc.send_signal(signal.SIGHUP)
129+
assert proc.stdout.readline() == '{0}\n'.format(signal.SIGHUP).encode('ascii')

0 commit comments

Comments
 (0)