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