Linux System Programming · intermediate · ~10 min
Collect a child's exit status.
wait(&status) and waitpid(pid, &status, opts) suspend the parent until a child terminates, returning the child's PID and exit status. Without wait, exited children linger as zombies — entries in the process table with no memory, holding only an exit code waiting to be collected.
In a fork-based program, the parent must collect each child's exit code or accept that zombies will pile up. On a long-running server that spawns hundreds of subprocesses an hour, missed wait calls eventually fill the kernel's process table and the system fails to fork new children.
Status macros. WIFEXITED(status) is true if the child exited normally; WEXITSTATUS(status) extracts the exit code. WIFSIGNALED / WTERMSIG tell you about signals. waitpid flags. WNOHANG makes wait non-blocking (returns 0 if no child has exited yet). SIGCHLD. When a child exits, the parent gets a SIGCHLD; you can install a handler that calls waitpid in a loop.
int status;
pid_t kid = waitpid(child, &status, 0);
if (WIFEXITED(status)) printf("exited with %d\n", WEXITSTATUS(status));
else if (WIFSIGNALED(status)) printf("killed by signal %d\n", WTERMSIG(status));
When a child exits, the kernel keeps a small record (the zombie) until the parent calls wait or waitpid. int waitpid(pid_t pid, int *status, int options) blocks (or polls with WNOHANG) until the specified child terminates.
Decode status with WIFEXITED + WEXITSTATUS for normal exits, WIFSIGNALED + WTERMSIG for signal kills.
int st;
waitpid(pid, &st, 0);
if (WIFEXITED(st)) printf("exit %d\n", WEXITSTATUS(st));
if (WIFSIGNALED(st)) printf("killed by signal %d\n", WTERMSIG(st));
ps -ef | grep defunct lists zombies — each is a child you forgot to wait on. Modern Linux has prctl(PR_SET_CHILD_SUBREAPER, 1) so a parent can claim grandchildren, useful in service managers.
Wait is about resource hygiene, not memory. The kernel keeps a small struct for each unreaped child; long-running servers must reap (or use SIGCHLD handler + waitpid-loop) to avoid accumulating them.
Every shell after every command, every web server with a per-connection child, cron, init/systemd's reaper.
_exit(7); have the parent print its exit code via WEXITSTATUS. 2. Fork 5 children and waitpid for each. 3. Install a SIGCHLD handler that calls waitpid(-1, &st, WNOHANG) in a loop.wait collects exited children's status and cleans them out of the process table. Pair every fork with a wait (or a SIGCHLD handler) to avoid zombies. The fork/exec/wait triad is the heart of Unix process management.