#include <stdio.h> #include <signal.h> #include <siginfo.h> #include <wait.h> #include <ucontext.h> /* * The previous example showed a signal handler. * This one shows a "signal action function" * The principle difference is that this method * allows us to more precisely determine what * caused a signal, &c. * * Send the child various signals and observe operation. * * see man pages: sigaction, siginfo, wait * see /usr/sys/includewait.h */ void ChildHandler (int sig, siginfo_t *sip, void *notused) { int status; printf ("The process generating the signal is PID: %d\n", sip->si_pid); fflush (stdout); status = 0; /* The WNOHANG flag means that if there's no news, we don't wait */ if (sip->si_pid == waitpid (sip->si_pid, &status, WNOHANG)) { /* A SIGCHLD doesn't necessarily mean death -- a quick check */ /* Not necessarily complete */ if (WIFEXITED(status)) { printf ("Voluntary exit.\n"); goto done; } if (WIFSTOPPED(status)) { printf ("Suspended.\n"); goto done; } if ( (WTERMSIG(status) <= 12) || (WTERMSIG(status) == 15)) { printf ("Croaked"); goto done; } printf ("Nothing interesting\n"); done:; } else { /* If there's no news, we're probably not interested, either */ printf ("Uninteresting\n"); } } int main() { struct sigaction action; action.sa_sigaction = ChildHandler; /* Note use of sigaction, not handler */ sigfillset (&action.sa_mask); action.sa_flags = SA_SIGINFO; /* Note flag - otherwise NULL in function */ sigaction (SIGCHLD, &action, NULL); fork(); while (1) { printf ("PID: %d\n", getpid()); sleep(1); } }