/** * Demonstration that SIGCHLD signals are not queued. * * The program below blocks SIGCHLD, then starts 3 children * which exit. After SIGCHLD is unblocked, only one * SIGCHLD is delivered, with the si_pid set to the first child's * pid. Three calls to waitpid() will be necessary to reap each child. * * Written by Godmar Back for CS 3214, Fall 2010. */ #include #include #include #include static void sigchld_handler(int signo, siginfo_t *info, void * _ctxt) { char buf[1024]; snprintf(buf, sizeof buf, "sigchld_handler called si_pid=%d\n", info->si_pid); write(1, buf, strlen(buf)); } int main() { int status; struct sigaction act; act.sa_sigaction = sigchld_handler; act.sa_flags = SA_SIGINFO; sigemptyset (&act.sa_mask); status = sigaction (SIGCHLD, &act, NULL); if (status) { perror ("sigaction"); exit (1); } // start and stop children #1, #2, #3 sigset_t block; sigemptyset(&block); sigaddset(&block, SIGCHLD); printf("Parent blocking SIGCHLD\n"); sigprocmask(SIG_BLOCK, &block, NULL); int i = 0; for (; i < 3; i++) { if (fork() == 0) { printf("Child %d exiting\n", getpid()); exit(0); } } printf("Parent unblocking SIGCHLD\n"); sigprocmask(SIG_UNBLOCK, &block, NULL); sleep(3); printf("Parent reaping children\n"); int rc; while ((rc = waitpid(-1, NULL, 0)) > 0) printf("Parent reaped child %d\n", rc); printf("Parent exiting\n"); return 0; }