/*
 * sigchld.c:
 * Demonstrate a signal-handling bug.
 *
 */

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

void
os_non_restarting_signal(int sig, void (*handler)(int))
{
/* Many systems have the SA_RESTART sigaction for specifying that a signal
should restart system calls. These include SunOS5, AIX, BSDI, IRIX, FreeBSD,
OSF1, Linux and HP-UX 10 (but *not* HP-UX 9). */

struct sigaction act;
act.sa_handler = handler;
sigemptyset(&(act.sa_mask));
act.sa_flags = 0;
sigaction(sig, &act, NULL);

}

#define TRUE 1
static sig_atomic_t sigchld_seen;

static void
main_sigchld_handler(int sig)
{
sig = sig;    /* Keep picky compilers happy */
os_non_restarting_signal(SIGCHLD, SIG_DFL);
sigchld_seen = TRUE;
}

void child_process(void) {
    //write(2, "<", 1);
    usleep(10000);
    //write(2, ">", 1);
    _exit(0);
}

int main(void) {
    int i;
    os_non_restarting_signal(SIGCHLD, main_sigchld_handler);
    for (i = 0; i < 50; ++i) {
        if (0 == fork())
            child_process();
    }
    while (1) {
        if (sigchld_seen) {
            while (0 != waitpid(-1, NULL, WNOHANG)) {
                //write(2, "w", 1);
                if (0 == fork())
                    child_process();
            }
            sigchld_seen = 0;
            os_non_restarting_signal(SIGCHLD, main_sigchld_handler);
        }
        usleep(1);
    }
    exit(0);
}

