/* sigExample.c * * Neal Nelson 2009.11.04 * Modified code from Nutt p91 illustrating signal handling * * Note that signals don't queue, so there is a race condition between * the parent sending SIGUSR2 and the parent sending SIGTERM * I guess the SIGTERM overwrites the SIGUSR2 without the sleep. * See the code below. * */ #include #include /* for pause() */ #include /* prototype must occur before sig_handler is referenced */ static void sig_handler(int); main() { int i, parent_pid, child_pid, status; /* prepare the sig_handler routine to catch SIGUSR1 and SIGUSR2 */ if (signal(SIGUSR1, sig_handler) == SIG_ERR) printf("Parent: Unable to create handler for SIGUSR1\n"); if (signal(SIGUSR2, sig_handler) == SIG_ERR) printf("Parent: Unable to create handler for SIGUSR2\n"); parent_pid = getpid(); if ((child_pid = fork()) == 0) /* child */ { printf("Child: raising SIGUSR1 signal to parent\n"); kill(parent_pid, SIGUSR1); for (;;) pause(); /* child busy wait for SIGUSR2 */ } else /* parent */ { printf("Parent: raising SIGUSR2 signal to child\n"); kill(child_pid, SIGUSR2); /* Without the sleep child doesn't catch interrupt before termination */ sleep(1); printf("Parent: terminating child ...\n"); kill(child_pid, SIGTERM); /* raise the SIGTERM signal to child */ wait(&status); /* parent wait for child termination */ printf("done.\n"); } } static void sig_handler(int signo) { switch(signo) { case SIGUSR1: printf("Parent: Received SIGUSR1 signal from child\n"); break; case SIGUSR2: printf("Child: Received SIGUSR2 signal from parent\n"); break; default: break; /* should never get here */ } return; }