462 Chapter 22
We continue by using the shell kill command to send a signal to the catch_rtsigs pro-
gram. As before, we see that the siginfo_t structure received by the handler includes
the process ID and user ID of the sending process, but in this case, the si_code value
is SI_USER:
Press Enter to see next shell prompt
$ echo $$ Display PID of shell
12780
$ kill -40 12842 Uses kill(2) to send a signal
$ caught signal 40
si_signo=40, si_code=0 (SI_USER), si_value=0
si_pid=12780, si_uid=1000 PID is that of the shell
Press Enter to see next shell prompt
$ kill 12842 Kill catch_rtsigs by sending SIGTERM
Caught 6 signals
Press Enter to see notification from shell about terminated background job
[1]+ Done ./catch_rtsigs 60
Listing 22-3: Handling realtime signals
––––––––––––––––––––––––––––––––––––––––––––––––––––– signals/catch_rtsigs.c
#define _GNU_SOURCE
#include <string.h>
#include <signal.h>
#include "tlpi_hdr.h"
static volatile int handlerSleepTime;
static volatile int sigCnt = 0; /* Number of signals received */
static volatile int allDone = 0;
static void /* Handler for signals established using SA_SIGINFO */
siginfoHandler(int sig, siginfo_t *si, void *ucontext)
{
/* UNSAFE: This handler uses non-async-signal-safe functions
(printf()); see Section 21.1.2) */
/* SIGINT or SIGTERM can be used to terminate program */
if (sig == SIGINT || sig == SIGTERM) {
allDone = 1;
return;
}
sigCnt++;
printf("caught signal %d\n", sig);
printf(" si_signo=%d, si_code=%d (%s), ", si->si_signo, si->si_code,
(si->si_code == SI_USER)? "SI_USER" :
(si->si_code == SI_QUEUE)? "SI_QUEUE" : "other");
printf("si_value=%d\n", si->si_value.sival_int);
printf(" si_pid=%ld, si_uid=%ld\n", (long) si->si_pid, (long) si->si_uid);
sleep(handlerSleepTime);
}