Create multiple timers, set from command-line arguments
Command-line arguments have form: seconds[:interval-seconds].
#define SIG SIGRTMAX /* Our timer notification signal */
int
main(int argc, char *argv[])
{
struct itimerspec ts;
struct sigaction sa;
struct sigevent sev;
timer_t *tidlist; /* Points to list of timer IDs */
int j;
char *cptr;
if (argc < 2)
usageErr("%s secs[:interval-secs]...\n", argv[0]);
Establish handler for timer notification signal:
sa.sa_flags = SA_SIGINFO; /* Pass siginfo_t struct to handler */
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIG, &sa, NULL) == -1) errExit("sigaction");
Using SA_SIGINFO causes handler to be invoked with a siginfo_t structure as second argument.
The fields that are set in this structure include:
Allocate array to hold timer IDs:
tidlist = calloc(argc - 1, sizeof(timer_t));
if (tidlist == NULL) errExit("malloc");
Create one timer for each command-line argument, and start the timers.
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIG;
/* Set up one timer for each command-line argument */
for (j = 0; j < argc - 1; j++) {
sev.sigev_value.sival_ptr = &tidlist[j];
/* So handler has the address of the timer ID */
if (timer_create(CLOCK_REALTIME, &sev, &tidlist[j]) == -1)
errExit("timer_create");
printf("Timer ID: %ld (%s)\n", (long) tidlist[j], argv[j + 1]);
ts.it_value.tv_sec = atoi(argv[j + 1]);
cptr = strchr(argv[j + 1], ':');
ts.it_interval.tv_sec = (cptr != NULL) ? atoi(cptr + 1) : 0;
ts.it_value.tv_nsec = ts.it_interval.tv_nsec = 0;
if (timer_settime(tidlist[j], 0, &ts, NULL) == -1)
errExit("timer_settime");
}
Wait for signals:
for (j = 0; ; j++)
pause();
} /* main */
This is the signal handler:
static void
handler(int sig, siginfo_t *si, void *uc)
{
timer_t *tidptr = si->si_value.sival_ptr;
/* UNSAFE: This handler uses non-async-signal-safe functions */
printf("[%s] Got signal %d\n", currTime("%T"), sig);
printf(" timer ID = %d\n", *tidptr);
printf(" timer_getoverrun() = %d\n", timer_getoverrun(*tidptr));
} /* handler */
(C) 2006, Michael Kerrisk