Ensure children are reaped periodically - sinit - suckless init | |
git clone git://git.suckless.org/sinit | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 170d599d58efee6c9be675a85c6e435d68e8a2de | |
parent 731f65fc82afcd474f4c682f9f0069e5c80c86dd | |
Author: sin <[email protected]> | |
Date: Sun, 18 Mar 2018 13:35:38 +0000 | |
Ensure children are reaped periodically | |
There is a pathological case where a parent receives SIGCHLD after its | |
child dies but does not reap it. After the parent dies, the child is | |
reparented to init but SIGCHLD is not redelivered. | |
To fix this, periodically check if there are zombies pending to be | |
reaped. | |
Diffstat: | |
M sinit.c | 6 +++++- | |
1 file changed, 5 insertions(+), 1 deletion(-) | |
--- | |
diff --git a/sinit.c b/sinit.c | |
@@ -7,7 +7,8 @@ | |
#include <stdlib.h> | |
#include <unistd.h> | |
-#define LEN(x) (sizeof (x) / sizeof *(x)) | |
+#define LEN(x) (sizeof (x) / sizeof *(x)) | |
+#define TIMEO 30 | |
static void sigpoweroff(void); | |
static void sigreap(void); | |
@@ -20,6 +21,7 @@ static struct { | |
} sigmap[] = { | |
{ SIGUSR1, sigpoweroff }, | |
{ SIGCHLD, sigreap }, | |
+ { SIGALRM, sigreap }, | |
{ SIGINT, sigreboot }, | |
}; | |
@@ -40,6 +42,7 @@ main(void) | |
sigprocmask(SIG_BLOCK, &set, NULL); | |
spawn(rcinitcmd); | |
while (1) { | |
+ alarm(TIMEO); | |
sigwait(&set, &sig); | |
for (i = 0; i < LEN(sigmap); i++) { | |
if (sigmap[i].sig == sig) { | |
@@ -63,6 +66,7 @@ sigreap(void) | |
{ | |
while (waitpid(-1, NULL, WNOHANG) > 0) | |
; | |
+ alarm(TIMEO); | |
} | |
static void |