| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- #include <unistd.h>
- #include <time.h>
- #include <signal.h>
- #include <stdio.h>
- #include <sys/queue.h>
- #include <stdlib.h>
- #include <string.h>
- #include <err.h>
- /*
- * signal and timer example
- *
- * timerTest.c
- */
- /*
- * map timer code to a string
- *
- */
- #define MAX_LEN_NAME 128
- SLIST_HEAD(slisthead, entry) head = SLIST_HEAD_INITIALIZER(head);
- struct slisthead *headp; /* Singly-linked List head. */
- struct entry {
- char *name;
- int code;
- SLIST_ENTRY (entry) entries; /* Singly-linked List. */
- } *np;
- /*
- * signal handler
- *
- */
- static int spankme;
- void
- sigHandler(int signo, siginfo_t * si, void * /* ucontext_t */ uap)
- {
- switch (signo) {
- case SIGALRM:
- /* timer timeout */
- SLIST_FOREACH(np, &head, entries) {
- if (np && np->code == si->si_value.sival_int) {
- printf("%s", np->name);
- fflush(stdout);
- break;
- }
- }
- if (np == NULL)
- printf("Timeout #%d, unknown.\n", si->si_value.sival_int);
- break;
- case SIGINFO:
- printf("no need to panic.\n");
- break;
- case SIGINT:
- /* exit flag */
- ++spankme;
- break;
- default:
- printf("sig:%di received.", signo);
- break;
- }
- }
- int
- main(int argc, char *argv[])
- {
- SLIST_INIT(&head);
- /* timer pointers */
- size_t nb_timers=0;
- if(argc>1){
- nb_timers=atoi(argv[1]);
- }
- if(nb_timers<1){
- nb_timers=5;
- }
- timer_t timerid[nb_timers];
- char *names[nb_timers];
-
- /* build text to display for each */
- for(size_t i=0;i<nb_timers;++i){
- names[i]=malloc(MAX_LEN_NAME);
- if(i==0){
- strncpy(names[i],".",MAX_LEN_NAME);
- continue;
- }
- if(MAX_LEN_NAME<=snprintf(names[i],MAX_LEN_NAME,"+%zu+",i*2+1)){
- warnx("string %zu shorten",i);
- }
- }
- /* signal */
- struct sigaction sa;
- sa.sa_handler = NULL;
- sa.sa_sigaction = &sigHandler;
- sa.sa_flags = SA_SIGINFO;
- sigemptyset(&sa.sa_mask);
- if (sigaction(SIGINFO, &sa, NULL)) {
- warn("SIGNFO not caught.");
- }
- if (sigaction(SIGALRM, &sa, NULL)) {
- err(2, "sigaction:ALARM");
- }
- if (sigaction(SIGINT, &sa, NULL)) {
- err(2, "sigaction:INTERRUPT");
- }
- /* timer */
- for (size_t i = 0; i < nb_timers; ++i) {
- if (timer_create(CLOCK_REALTIME, NULL, &timerid[i])) {
- warn("timer_create failed for %zu", i);
- continue;
- }
- /* 3 -> TIMER_MAX stored into timerid->oshandle */
- printf("Timer #%d now created at address %p.\n", timer_oshandle_np(timerid[i]),timerid[i]);
- np = malloc(sizeof(struct entry)); /* Insert at the head. */
- np->code = timer_oshandle_np(timerid[i]);
- np->name=names[i];
- SLIST_INSERT_HEAD(&head, np, entries);
- /* Set values and start timer */
- struct itimerspec its;
- its.it_interval.tv_sec = 1 + i * 2;
- its.it_interval.tv_nsec = 0;
- its.it_value.tv_sec = its.it_interval.tv_sec;
- its.it_value.tv_nsec = 0;
- if (timer_settime(timerid[i], 0, &its, NULL)) {
- warn("timer_settime failed for %zu", i);
- }
- }
- printf("waiting...\n");
- for (; !spankme;) {
- pause();
- } //loop
- printf("\nbye.\n");
- for (size_t i = 0; i < nb_timers; ++i) {
- timer_delete(timerid[i]);
- }
- while (!SLIST_EMPTY(&head)) {
- np = SLIST_FIRST(&head);
- SLIST_REMOVE_HEAD(&head, entries);
- free(np->name);
- free(np);
- }
- }
|