In DIGITAL UNIX Version 4.0D, the early child exit notification feature alerts a parent process when a child process is about to dump core and exit abnormally with a signal. Because writing a core file can take an indeterminate period of time, early notification allows the parent process to take immediate action to recover from the child process' impending termination.
A parent process requests early exit notification when establishing
a signal handler for the
SIGCHLD
signal with the
sigaction
system call. The
sigaction
flag
SA_CLDNOTIFY
requests early notification; you should use this flag in combination
with the
SA_SIGINFO
flag to provide complete information about the terminating child.
Setting the
SA_CLDNOTIFY
flag in combination with
SA_SIGINFO
causes two
SIGCHLD
signals to be sent to the parent for each abnormal termination of a
child process:
siginfo
structure with the
si_signo
field set to
SIGCHLD,
the
si_code
field set to
CLD_SIGEXITING,
and the
si_pid
field set to the process ID of the child process that is about to
write a core file and terminate abnormally. This signal tells the
parent process that it can start its failover operation or take other
appropriate action.
siginfo
structure with the
si_signo
field set to
SIGCHLD,
the
si_code
field set to
CLD_DUMPED,
and the
si_pid
field set to the process ID of the child that has terminated
abnormally. This signal tells the parent process that the child process
is now a zombie and should be cleaned with a call to
wait.
Note that the use of
SA_CLDNOTIFY
in the recommended combination with
SA_SIGINFO
in effect turns the
SIGCHLD
signal into a "realtime" signal. Every instance of the
SIGCHLD
signal is queued first-in, first-out to the parent
process. Every early child exit and every final child exit
generates a
SIGCHLD
signal to the parent. Contrast this behavior with
the default behavior of the
SIGCHLD
signal, in which multiple child exit signals can be compressed into a
single signal when the
SIGCHLD
signal is already pending for the parent process.
The following program shows an example of using early notification of child process termination.
#include <stdio.h>
#include <sys/types.h>
#include <sys/signal.h>
#include <sys/siginfo.h>
volatile pid_t kid1, kid2;
/*
* Handler for SIGCHLD signal. Note: printf() calls
* are technically unsupported from signal handlers
* and are shown for illustrative purposes only.
*/
void
sigchld_handler(int sig, siginfo_t *sip, void *extra)
{
pid_t kid;
kid = sip->si_pid;
if (sip->si_code == CLD_SIGEXITING) {
printf("SIGEXITING: Got signal %d, si_code %d"
" for kid %d\n",
sip->si_signo, sip->si_code, kid);
} else if (sip->si_code == CLD_DUMPED) {
printf("EXITED: Got signal %d, si_code %d"
" for kid %d\n",
sip->si_signo, sip->si_code, kid);
kid = wait(0);
printf("Parent got PID %d exiting\n", kid);
if (kid == kid1)
kid1 = 0;
else if (kid == kid2)
kid2 = 0;
}
}
main()
{
struct sigaction sa;
int ret;
/*
* Set up SIGCHLD handler for early exit
* notification.
*/
sa.sa_sigaction = sigchild_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_CLDNOTIFY|SA_SIGINFO;
ret = sigaction(SIGCHLD, &sa, 0);
if (ret) {
perror("sigaction");
exit(1);
}
/*
* Create 2 children to die with SIGABRT
* and create core files.
*/
kid1 = fork();
if (kid1)
printf("Parent forked %d\n", kid1);
else {
/*
* First child...
*/
sleep(1);
printf("Kid %d will now die with core file...\n",
getpid());
abort();
/*NOTREACHED*/
}
kid2 = fork();
if (kid2)
printf("Parent forked %d\n", kid2);
else {
/*
* Second child...
*/
sleep(1);
printf("Kid %d will now die with core file...\n",
getpid());
abort();
/*NOTREACHED*/
}
/*
* Parent: keep busy until children exit.
*/
while (kid1 || kid2)
;
;
/*
* Children have exited: verify by printing zeros.
*/
printf("Parent: done -- kid1 %d, kid2 %d\n", kid1, kid2);
;
/*
* Children have exit: verify by printing zeros.
*/
printf("Parent: done -- kid1 %d, kid2 %d\n", kid1, kid2);
}