commit adef641816607a857d793ab14403ae79404a7dc9
parent e3d1a0f57fe102bb5bbace085e02df18dbc9e7df
Author: Friedel Schon <[email protected]>
Date: Sun, 30 Apr 2023 00:10:03 +0200
refactoring sigremap
Diffstat:
M | src/exec/sigremap.c | | | 181 | +++++++++++++++++++++++++++++++++++++++---------------------------------------- |
1 file changed, 90 insertions(+), 91 deletions(-)
diff --git a/src/exec/sigremap.c b/src/exec/sigremap.c
@@ -1,24 +1,24 @@
/* Copyright (c) 2015 Yelp, Inc.
- With modification 2023 Friedel Schon
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
+ With modification 2023 Friedel Schon
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ */
/*
* sigremap is a simple wrapper program designed to run as PID 1 and pass
@@ -35,6 +35,7 @@
#include <assert.h>
#include <errno.h>
#include <getopt.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -65,34 +66,25 @@
// User-specified signal rewriting.
int signal_remap[MAXSIG + 1] = { [0 ... MAXSIG] = -1 };
// One-time ignores due to TTY quirks. 0 = no skip, 1 = skip the next-received signal.
-char signal_temporary_ignores[MAXSIG + 1] = { [0 ... MAXSIG] = 0 };
+bool signal_temporary_ignores[MAXSIG + 1] = { [0 ... MAXSIG] = false };
-pid_t child_pid = -1;
-char debug = 0;
-char use_setsid = 1;
+pid_t child_pid = -1;
+bool debug = false;
+bool use_setsid = true;
-int translate_signal(int signum) {
- if (signum <= 0 || signum > MAXSIG) {
- return signum;
- } else {
- int translated = signal_remap[signum];
- if (translated == -1) {
- return signum;
- } else {
- DEBUG("Translating signal %d to %d.\n", signum, translated);
- return translated;
- }
+void forward_signal(int signum) {
+ if (signum >= 0 && signum <= MAXSIG && signal_remap[signum] != -1) {
+ DEBUG("Translating signal %d to %d.\n", signum, signal_remap[signum]);
+ signum = signal_remap[signum];
}
-}
-void forward_signal(int signum) {
- signum = translate_signal(signum);
- if (signum != 0) {
- kill(use_setsid ? -child_pid : child_pid, signum);
- DEBUG("Forwarded signal %d to children.\n", signum);
- } else {
+ if (signum == 0) {
DEBUG("Not forwarding signal %d to children (ignored).\n", signum);
+ return;
}
+
+ kill(use_setsid ? -child_pid : child_pid, signum);
+ DEBUG("Forwarded signal %d to children.\n", signum);
}
/*
@@ -122,7 +114,7 @@ void handle_signal(int signum) {
DEBUG("Ignoring tty hand-off signal %d.\n", signum);
signal_temporary_ignores[signum] = 0;
} else if (signum == SIGCHLD) {
- int status, exit_status;
+ int status, exit_status;
pid_t killed_pid;
while ((killed_pid = waitpid(-1, &status, WNOHANG)) > 0) {
if (WIFEXITED(status)) {
@@ -135,13 +127,20 @@ void handle_signal(int signum) {
}
if (killed_pid == child_pid) {
- forward_signal(SIGTERM); // send SIGTERM to any remaining children
+ kill(use_setsid ? -child_pid : child_pid, SIGTERM); // send SIGTERM to any remaining children
DEBUG("Child exited with status %d. Goodbye.\n", exit_status);
exit(exit_status);
}
}
} else {
- forward_signal(signum);
+ if (signum <= MAXSIG && signal_remap[signum] != -1) {
+ DEBUG("Translating signal %d to %d.\n", signum, signal_remap[signum]);
+ signum = signal_remap[signum];
+ }
+
+ kill(use_setsid ? -child_pid : child_pid, signum);
+ DEBUG("Forwarded signal %d to children.\n", signum);
+
if (signum == SIGTSTP || signum == SIGTTOU || signum == SIGTTIN) {
DEBUG("Suspending self due to TTY signal.\n");
kill(getpid(), SIGSTOP);
@@ -151,29 +150,29 @@ void handle_signal(int signum) {
void print_help(char* argv[]) {
fprintf(stderr,
- "Usage: %s [option] [old-signal=new-signal] command [[arg] ...]\n"
- "\n"
- "sigremap is a simple process supervisor that forwards signals to children.\n"
- "It is designed to run as PID1 in minimal container environments.\n"
- "\n"
- "Optional arguments:\n"
- " -s, --single Run in single-child mode.\n"
- " In this mode, signals are only proxied to the\n"
- " direct child and not any of its descendants.\n"
- " -r, --remap s:r remap received signal s to new signal r before proxying.\n"
- " To ignore (not proxy) a signal, remap 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"
- "\n"
- "Full help is available online at https://github.com/Yelp/sigremap\n",
- argv[0]);
+ "Usage: %s [option] [old-signal=new-signal] command [[arg] ...]\n"
+ "\n"
+ "sigremap is a simple process supervisor that forwards signals to children.\n"
+ "It is designed to run as PID1 in minimal container environments.\n"
+ "\n"
+ "Optional arguments:\n"
+ " -s, --single Run in single-child mode.\n"
+ " In this mode, signals are only proxied to the\n"
+ " direct child and not any of its descendants.\n"
+ " -r, --remap s:r remap received signal s to new signal r before proxying.\n"
+ " To ignore (not proxy) a signal, remap 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"
+ "\n"
+ "Full help is available online at https://github.com/Yelp/dumb-init\n",
+ argv[0]);
}
char** parse_command(int argc, char* argv[]) {
- int opt;
+ int opt;
struct option long_options[] = {
{ "help", no_argument, NULL, 'h' },
{ "single", no_argument, NULL, 's' },
@@ -187,13 +186,13 @@ char** parse_command(int argc, char* argv[]) {
print_help(argv);
exit(0);
case 'v':
- debug = 1;
+ debug = true;
break;
case 'V':
// fprintf(stderr, "sigremap v%.*s", VERSION_len, VERSION);
exit(0);
case 'c':
- use_setsid = 0;
+ use_setsid = false;
break;
default:
exit(1);
@@ -207,7 +206,7 @@ char** parse_command(int argc, char* argv[]) {
if ((new = strchr(argv[0], '=')) == NULL)
break;
- old = argv[0];
+ old = argv[0];
*new = '\0';
new ++;
@@ -228,10 +227,10 @@ char** parse_command(int argc, char* argv[]) {
if (argc < 1) {
fprintf(
- stderr,
- "Usage: %s [option] program [args]\n"
- "Try %s --help for full usage.\n",
- argv[0], argv[0]);
+ stderr,
+ "Usage: %s [option] program [args]\n"
+ "Try %s --help for full usage.\n",
+ argv[0], argv[0]);
exit(1);
}
@@ -253,7 +252,7 @@ void dummy(int signum) {
}
int main(int argc, char* argv[]) {
- char** cmd = parse_command(argc, argv);
+ char** cmd = parse_command(argc, argv);
sigset_t all_signals;
sigfillset(&all_signals);
sigprocmask(SIG_BLOCK, &all_signals, NULL);
@@ -272,9 +271,9 @@ int main(int argc, char* argv[]) {
if (use_setsid) {
if (ioctl(STDIN_FILENO, TIOCNOTTY) == -1) {
DEBUG(
- "Unable to detach from controlling tty (errno=%d %s).\n",
- errno,
- strerror(errno));
+ "Unable to detach from controlling tty (errno=%d %s).\n",
+ errno,
+ strerror(errno));
} else {
/*
* When the session leader detaches from its controlling tty via
@@ -303,32 +302,32 @@ int main(int argc, char* argv[]) {
if (use_setsid) {
if (setsid() == -1) {
PRINTERR(
- "Unable to setsid (errno=%d %s). Exiting.\n",
- errno,
- strerror(errno));
+ "Unable to setsid (errno=%d %s). Exiting.\n",
+ errno,
+ strerror(errno));
exit(1);
}
if (ioctl(STDIN_FILENO, TIOCSCTTY, 0) == -1) {
DEBUG(
- "Unable to attach to controlling tty (errno=%d %s).\n",
- errno,
- strerror(errno));
+ "Unable to attach to controlling tty (errno=%d %s).\n",
+ errno,
+ strerror(errno));
}
DEBUG("setsid complete.\n");
}
- execvp(cmd[0], &cmd[0]);
+ execvp(cmd[0], cmd);
// if this point is reached, exec failed, so we should exit nonzero
PRINTERR("%s: %s\n", cmd[0], strerror(errno));
- return 2;
- } else {
- /* parent */
- DEBUG("Child spawned with PID %d.\n", child_pid);
- for (;;) {
- int signum;
- sigwait(&all_signals, &signum);
- handle_signal(signum);
- }
+ _exit(2);
+ }
+
+ /* parent */
+ DEBUG("Child spawned with PID %d.\n", child_pid);
+ for (;;) {
+ int signum;
+ sigwait(&all_signals, &signum);
+ handle_signal(signum);
}
}