💾 Archived View for thrig.me › blog › 2024 › 02 › 14 › child.c captured on 2024-12-17 at 11:55:11.
⬅️ Previous capture (2024-03-21)
-=-=-=-=-=-=-
// child.c - ZOMBIES!! or various tests for how SIGCHILD handling // behaves. there are things to TWEAK #include <sys/wait.h> #include <err.h> #include <errno.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> void handle_child(int unused) { // just because there is a child handler does not mean it will // do anything sensible, or there could be bugs, etc printf("SIGCHLD %d\n", getpid()); } void default_case(void) { int status; pid_t pid, ret; // TWEAK either the default or with a handler signal(SIGCHLD, SIG_DFL); //signal(SIGCHLD, handle_child); pid = fork(); if (pid < 0) err(1, "fork"); if (pid == 0) { sleep(1); _exit(42); // make the exit status more distinctive } else { sleep(5); raise(SIGCHLD); errno = 0; ret = waitpid(WAIT_ANY, &status, WNOHANG); printf("WAITPID %d ret=%d status=%d errno=%d\n", pid, ret, status, errno); } } // ignoring SIGCHILD will cause zombies not to accumulate, at least on // modern unix systems that follow the SUSv3 specification void ignore_child(void) { int status; pid_t pid, ret; // TWEAK with this commented out the child should become a // zombie for about 10 seconds signal(SIGCHLD, SIG_IGN); pid = fork(); if (pid < 0) err(1, "fork"); if (pid == 0) { sleep(1); _exit(42); // make the exit status more distinctive } else { sleep(10); // allow time to run process tools elsewhere //abort(); errno = 0; ret = waitpid(WAIT_ANY, &status, WNOHANG); printf("WAITPID %d ret=%d status=%d errno=%d\n", pid, ret, status, errno); } } void inherit_the_signals(void) { int status; pid_t pid, ret, another_pid; // TWEAK SIG_IGN is probably not enough sigset_t block; sigemptyset(&block); sigaddset(&block, SIGCHLD); sigprocmask(SIG_BLOCK, &block, NULL); //signal(SIGCHLD, SIG_IGN); pid = fork(); if (pid < 0) err(1, "fork"); if (pid == 0) { signal(SIGCHLD, handle_child); another_pid = fork(); if (another_pid < 0) err(1, "fork"); if (another_pid == 0) { sleep(1); _exit(42); // make the exit status more distinctive } else { sleep(5); errno = 0; ret = waitpid(WAIT_ANY, &status, WNOHANG); printf("WAITPID %d ret=%d status=%d errno=%d\n", another_pid, ret, status, errno); } } else { wait(NULL); } } int main(int argc, char *argv[]) { // TWEAK call one of these and fiddle with the function in // question as need be //default_case(); //ignore_child(); //inherit_the_signals(); }