Ten Thousand Defunct Workers

This accept loop has served traffic for a week. ps now shows several thousand <defunct> children, and fork() has started failing with EAGAIN.

for (;;) {
    int fd = accept(listen_fd, NULL, NULL);
    if (fd < 0) continue;

    pid_t pid = fork();
    if (pid == 0) {
        close(listen_fd);
        handle_request(fd);
        _exit(0);
    }
    close(fd);
}

Which change removes the zombies while keeping the server concurrent?

A

Set FD_CLOEXEC on listen_fd so the child does not inherit it

B

Call signal(SIGCHLD, SIG_IGN); once before entering the loop

C

Add wait(NULL); immediately after close(fd);

D

Add waitpid(pid, NULL, WNOHANG); immediately after close(fd);