| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- #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>
- #include <sys/file.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) {
- flockfile(stdout);
- printf("%s", np->name);
- fflush(stdout);
- funlockfile(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:%d received.", signo);
- break;
- }
- }
- int
- main(int argc, char *argv[])
- {
- SLIST_INIT(&head);
- /* timer pointers */
- size_t nb_timers = 5;
- if (argc > 1) {
- nb_timers = atoi(argv[1]);
- }
- if (nb_timers < 1) {
- fprintf(stderr, "Invalid timer number.\n");
- abort();
- }
- 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 */
- 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("Timer %s now created at interval %ld.\n", np->name, its.it_interval.tv_sec);
- }
- printf("waiting...\n");
- for (; !spankme;) {
- pause();
- }
- 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);
- }
- }
|