aboutsummaryrefslogtreecommitdiff
path: root/fcgiwrap.c
diff options
context:
space:
mode:
authorFurkan Sahin <furkan-dev@proton.me>2023-09-10 04:36:16 -0500
committerFurkan Sahin <furkan-dev@proton.me>2023-09-10 04:36:16 -0500
commit059f7095e327003031d91a9766e3a46f9223bbe7 (patch)
treef04ca58f39d839108dc472bcd3ae1faf976a70c4 /fcgiwrap.c
parentf09a4271d3f306d57f0f9a4b169c4bfd46201370 (diff)
Kill all child processes on parent SIGTERMmasterinfanticide-on-sigterm
When attached to a terminal, a SIGINT signal is sent to the parent and all children, instructing them to exit. In some environments including docker, only the parent receives the SIGTERM and is responsible for propagating it to the children. This patch kills all child processes when the parent receives a SIGTERM or a SIGINT.
Diffstat (limited to 'fcgiwrap.c')
-rw-r--r--fcgiwrap.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/fcgiwrap.c b/fcgiwrap.c
index 5b8af47..123d279 100644
--- a/fcgiwrap.c
+++ b/fcgiwrap.c
@@ -62,6 +62,12 @@
# define NORETURN
#endif
+#if defined(__GNUC__)
+# define UNUSED __attribute__((__unused__))
+#else
+# define UNUSED
+#endif
+
#define FCGI_FD 0
extern char **environ;
@@ -646,6 +652,8 @@ static void fcgiwrap_main(void)
while (FCGI_Accept() >= 0 && !sigint_received) {
handle_fcgi_request();
}
+
+ close(FCGI_FD);
}
static volatile sig_atomic_t nrunning;
@@ -665,21 +673,26 @@ static void sigchld_handler(int dummy)
}
}
+static volatile sig_atomic_t stop_requested;
+
+static void stop_request_handler(int UNUSED signum) {
+ stop_requested = 1;
+}
+
static void prefork(int nchildren)
{
int startup = 1;
- if (nchildren == 1) {
- return;
- }
-
signal(SIGCHLD, sigchld_handler);
+ signal(SIGINT, stop_request_handler);
+ signal(SIGTERM, stop_request_handler);
- while (1) {
+ while (!stop_requested) {
while (nrunning < nchildren) {
pid_t pid = fork();
if (pid == 0) {
- return;
+ fcgiwrap_main();
+ exit(0);
} else if (pid != -1) {
nrunning++;
} else {
@@ -695,6 +708,10 @@ static void prefork(int nchildren)
startup = 0;
pause();
}
+
+ if(killpg(0, SIGTERM) != 0) {
+ fprintf(stderr, "killpg() encountered an error, child processes may have to be killed");
+ }
}
static int listen_on_fd(int fd) {
@@ -891,10 +908,11 @@ int main(int argc, char **argv)
}
}
- prefork(nchildren);
- fcgiwrap_main();
-
- close(FCGI_FD);
+ if(nchildren > 1) {
+ prefork(nchildren);
+ } else {
+ fcgiwrap_main();
+ }
if (fd && socket_url) { // fd > 0 indicates a socket was setup by us
const char *p = socket_url;