Skip to content

Commit

Permalink
Merge pull request #86 from chriskuehl/add-signal-ignoring
Browse files Browse the repository at this point in the history
Add ability to ignore (not proxy) signals
  • Loading branch information
chriskuehl authored Jun 14, 2016
2 parents 859cfa6 + 1a7c635 commit 2d5483d
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 6 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
18 changes: 12 additions & 6 deletions dumb-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
}

/*
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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 {
Expand All @@ -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;
}

Expand Down
2 changes: 2 additions & 0 deletions tests/cli_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
18 changes: 18 additions & 0 deletions tests/proxies_signals_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')

0 comments on commit 2d5483d

Please sign in to comment.