/* signaldef.c - A modified version of Stevens signal function (page 120 of Vol.1, Network Programming). This program binds the signal SIGCLD to a handler sig_cld, then it loops ten times. In each iteration it creates a child and pauses. The handler is called when the child terminates. It collects and prints out information about the defunct chil`d. Notice that it is implemented as a loop because multiple SIGCLD signals may result in a single signal event. */ #include #include #include #include #include #include typedef void Sigfunc(int); /* Sigfunc is type of function with one int arg, and void return */ Sigfunc * signal(int signo, Sigfunc *func) { struct sigaction act, oact; act.sa_handler = func; sigemptyset(&act.sa_mask); act.sa_flags = 0; #ifdef SA_RESTART if (signo != SIGALRM) act.sa_flags |= SA_RESTART; #endif if (sigaction(signo, &act, &oact) < 0) return (SIG_ERR); return (oact.sa_handler); } static void sig_cld(); int main() { pid_t pid; int i; if (signal(SIGCLD, sig_cld) == SIG_ERR) { printf("signal error\n"); exit(1);} for (i=0; i < 10; i++){ if ( (pid = fork()) < 0) { printf("fork error\n"); exit(1);} else if (pid == 0) { /* child */ sleep(2); exit(0); } pause(); /* parent */ } exit(0); } static void sig_cld() { pid_t pid; int status; printf("SIGCLD received, "); while ( (pid = waitpid(-1, &status, WNOHANG)) > 0){ printf("child pid = %d terminated\n", pid); } printf ("Returning from handler\n"); return; }