Return to the Lab #4
Page
#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);
}
}