Rewrite arbitrary signals, and update tests
We've decided to allow arbitrary signal rewriting, not just SIGTERM rewriting. To use, call dumb-init with the '-r s:r' option, which will rewrite signum s to signum r. Only signals 1-31 are allowed to be rewritten, which should cover all the signals we need to cover. Note that this commit does not add new tests, it only fixes the existing broken test.
This commit is contained in:
parent
3b6e9f256f
commit
6f6b51f869
2 changed files with 47 additions and 15 deletions
59
dumb-init.c
59
dumb-init.c
|
@ -30,18 +30,24 @@
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define MAXSIG 32
|
||||||
|
|
||||||
|
int signal_rewrite[MAXSIG] = {
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7,
|
||||||
|
8, 9, 10, 11, 12, 13, 14, 15,
|
||||||
|
16, 17, 18, 19, 20, 21, 22, 23,
|
||||||
|
24, 25, 26, 27, 28, 29, 30, 31
|
||||||
|
};
|
||||||
|
|
||||||
pid_t child_pid = -1;
|
pid_t child_pid = -1;
|
||||||
char debug = 0;
|
char debug = 0;
|
||||||
char use_setsid = 1;
|
char use_setsid = 1;
|
||||||
int sigterm_replacement = 15;
|
|
||||||
|
|
||||||
|
|
||||||
int translate_signal(int signum) {
|
int translate_signal(int signum) {
|
||||||
switch (signum) {
|
if (signum < 0 || signum >= MAXSIG) {
|
||||||
case SIGTERM:
|
|
||||||
return sigterm_replacement;
|
|
||||||
default:
|
|
||||||
return signum;
|
return signum;
|
||||||
|
} else {
|
||||||
|
return signal_rewrite[signum];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +143,7 @@ void print_help(char *argv[]) {
|
||||||
" -c, --single-child Run in single-child mode.\n"
|
" -c, --single-child Run in single-child mode.\n"
|
||||||
" 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"
|
||||||
" -s, --signal Signal to use in place of SIGTERM.\n"
|
" -r, --rewrite s:r Rewrite signum s to signum r before proxying.\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"
|
||||||
|
@ -148,22 +154,47 @@ void print_help(char *argv[]) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_rewrite_signum_help() {
|
||||||
void write_sigterm_replacement(char *arg) {
|
fprintf(
|
||||||
sigterm_replacement = strtol(arg, NULL, 10);
|
stderr,
|
||||||
|
"Usage: -r option takes <signum>:<signum>, where <signum> "
|
||||||
|
"is between 1 and %d.\n"
|
||||||
|
"Use --help for full usage.\n",
|
||||||
|
MAXSIG
|
||||||
|
);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rewrite_signum(char *arg) {
|
||||||
|
char *rest;
|
||||||
|
int signum, replacement;
|
||||||
|
|
||||||
|
signum = strtol(arg, &rest, 10);
|
||||||
|
|
||||||
|
if (*rest != ':') {
|
||||||
|
print_rewrite_signum_help();
|
||||||
|
}
|
||||||
|
|
||||||
|
replacement = strtol(++rest, NULL, 10);;
|
||||||
|
|
||||||
|
if (signum <= 0 || signum > MAXSIG ||
|
||||||
|
replacement <= 0 || replacement > MAXSIG) {
|
||||||
|
print_rewrite_signum_help();
|
||||||
|
}
|
||||||
|
|
||||||
|
signal_rewrite[signum] = replacement;
|
||||||
|
}
|
||||||
|
|
||||||
char **parse_command(int argc, char *argv[]) {
|
char **parse_command(int argc, char *argv[]) {
|
||||||
int opt;
|
int opt;
|
||||||
struct option long_options[] = {
|
struct option long_options[] = {
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{"single-child", no_argument, NULL, 'c'},
|
{"single-child", no_argument, NULL, 'c'},
|
||||||
{"signal", required_argument, NULL, 's'},
|
{"rewrite", required_argument, NULL, 'r'},
|
||||||
{"verbose", no_argument, NULL, 'v'},
|
{"verbose", no_argument, NULL, 'v'},
|
||||||
{"version", no_argument, NULL, 'V'},
|
{"version", no_argument, NULL, 'V'},
|
||||||
};
|
};
|
||||||
while ((opt = getopt_long(argc, argv, "+hvVcs:", long_options, NULL)) != -1) {
|
while ((opt = getopt_long(argc, argv, "+hvVcr:", long_options, NULL)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'h':
|
case 'h':
|
||||||
print_help(argv);
|
print_help(argv);
|
||||||
|
@ -177,8 +208,8 @@ char **parse_command(int argc, char *argv[]) {
|
||||||
case 'c':
|
case 'c':
|
||||||
use_setsid = 0;
|
use_setsid = 0;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 'r':
|
||||||
write_sigterm_replacement(optarg);
|
rewrite_signum(optarg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
@ -40,6 +40,7 @@ def test_help_message(flag, both_debug_modes, both_setsid_modes, current_version
|
||||||
b' -c, --single-child Run in single-child mode.\n'
|
b' -c, --single-child Run in single-child mode.\n'
|
||||||
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 signum s to signum r before proxying.\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'
|
||||||
|
|
Loading…
Reference in a new issue