When a child process stops or terminates, SIGCHILD is sent to the parent process. The default response to the signal is to ignore it. The signal can be caught and the exit status form the child process can be obtained by immediately calling wait(2) and wait3(3C). This allows zombie process entries to be removed as quickly as possible. Example 5-2 demonstrates installing a handler that catches SIGCHILD.
#include <stdio.h> #include <signal.h> #include <sys/wait.h> #include <sys/resource.h> void proc_exit() { int wstat; union wait wstat; while (TRUE) { pid = wait3 (&wstat, WNOHANG, (struct rusage *)NULL ); if (pid == 0) return; else if (pid == -1) return; else printf ("Return code: %d\n", wstat.w_retcode); } } main () { signal (SIGCHILD, proc_exit); switch (fork()) { case -1: perror ("main: fork"); exit (0); case 0: printf ("I'm alive (terporarily)\n"); exit (rand()); default: pause(); } }
SIGCHILD catchers are usually set up as part of process initialization. They must be set before a child process is forked. A typical SIGCHILD handler simply retrieves the child process's exit status.