/* sigAck.c * * Neal Nelson 2009.11.04 * * Separate signal handlers for parent and child. Note that the child * has to be created before it can register its signal handler. * Child exits on its own here instead of by termination by the parent. * * See man pause. pause waits for a signal before continuing. * * */ #include #include /* for pause() */ #include #include /* prototypes must occur before sig handlers are referenced */ static void parent_handler(int); static void child_handler(int); main() { int i, parent_pid, child_pid, status; /* prepare the parent_handler to catch SIGUSR1 */ if (signal(SIGUSR1, parent_handler) == SIG_ERR) printf("Parent: Unable to create handler for SIGUSR1\n"); parent_pid = getpid(); if ((child_pid = fork()) == 0) /* child */ { /* prepare the child_handler to catch SIGUSR2 */ if (signal(SIGUSR2, child_handler) == SIG_ERR) printf("Child: Unable to create handler for SIGUSR2\n"); printf("Child: raising SIGUSR1 signal to parent\n"); kill(parent_pid, SIGUSR1); pause(); /* child pause for SIGUSR2 */ printf("Child: OK, I'm back from the SIGUSR2\n"); printf("Child: exit(0)\n"); exit(0); } else /* parent */ { printf("Parent: raising SIGUSR2 signal to child\n"); kill(child_pid, SIGUSR2); /* Child exits on its own, we don't kill, and now we don't need the sleep * sleep(1); * printf("Parent: terminating child ...\n"); * kill(child_pid, SIGTERM); */ wait(&status); /* parent wait for child termination */ printf("Parent: we're done.\n"); } } static void parent_handler(int signo) { switch(signo) { case SIGUSR1: printf("Parent: received SIGUSR1 signal from child\n"); break; default: break; /* should never get here */ } return; } static void child_handler(int signo) { switch(signo) { case SIGUSR2: printf("Child: received SIGUSR2 signal from parent\n"); break; default: break; /* should never get here */ } return; }