timerTest.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include <unistd.h>
  2. #include <time.h>
  3. #include <signal.h>
  4. #include <stdio.h>
  5. #include <sys/queue.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <err.h>
  9. /*
  10. * signal and timer example
  11. *
  12. * timerTest.c
  13. */
  14. /*
  15. * map timer code to a string
  16. *
  17. */
  18. #define MAX_LEN_NAME 128
  19. SLIST_HEAD(slisthead, entry) head = SLIST_HEAD_INITIALIZER(head);
  20. struct slisthead *headp; /* Singly-linked List head. */
  21. struct entry {
  22. char *name;
  23. int code;
  24. SLIST_ENTRY (entry) entries; /* Singly-linked List. */
  25. } *np;
  26. /*
  27. * signal handler
  28. *
  29. */
  30. static int spankme;
  31. void
  32. sigHandler(int signo, siginfo_t * si, void * /* ucontext_t */ uap)
  33. {
  34. switch (signo) {
  35. case SIGALRM:
  36. /* timer timeout */
  37. SLIST_FOREACH(np, &head, entries) {
  38. if (np && np->code == si->si_value.sival_int) {
  39. printf("%s", np->name);
  40. fflush(stdout);
  41. break;
  42. }
  43. }
  44. if (np == NULL)
  45. printf("Timeout #%d, unknown.\n", si->si_value.sival_int);
  46. break;
  47. case SIGINFO:
  48. printf("no need to panic.\n");
  49. break;
  50. case SIGINT:
  51. /* exit flag */
  52. ++spankme;
  53. break;
  54. default:
  55. printf("sig:%di received.", signo);
  56. break;
  57. }
  58. }
  59. int
  60. main(int argc, char *argv[])
  61. {
  62. SLIST_INIT(&head);
  63. /* timer pointers */
  64. size_t nb_timers=0;
  65. if(argc>1){
  66. nb_timers=atoi(argv[1]);
  67. }
  68. if(nb_timers<1){
  69. nb_timers=5;
  70. }
  71. timer_t timerid[nb_timers];
  72. char *names[nb_timers];
  73. /* build text to display for each */
  74. for(size_t i=0;i<nb_timers;++i){
  75. names[i]=malloc(MAX_LEN_NAME);
  76. if(i==0){
  77. strncpy(names[i],".",MAX_LEN_NAME);
  78. continue;
  79. }
  80. if(MAX_LEN_NAME<=snprintf(names[i],MAX_LEN_NAME,"+%zu+",i*2+1)){
  81. warnx("string %zu shorten",i);
  82. }
  83. }
  84. /* signal */
  85. struct sigaction sa;
  86. sa.sa_handler = NULL;
  87. sa.sa_sigaction = &sigHandler;
  88. sa.sa_flags = SA_SIGINFO;
  89. sigemptyset(&sa.sa_mask);
  90. if (sigaction(SIGINFO, &sa, NULL)) {
  91. warn("SIGNFO not caught.");
  92. }
  93. if (sigaction(SIGALRM, &sa, NULL)) {
  94. err(2, "sigaction:ALARM");
  95. }
  96. if (sigaction(SIGINT, &sa, NULL)) {
  97. err(2, "sigaction:INTERRUPT");
  98. }
  99. /* timer */
  100. for (size_t i = 0; i < nb_timers; ++i) {
  101. if (timer_create(CLOCK_REALTIME, NULL, &timerid[i])) {
  102. warn("timer_create failed for %zu", i);
  103. continue;
  104. }
  105. /* 3 -> TIMER_MAX stored into timerid->oshandle */
  106. printf("Timer #%d now created at address %p.\n", timer_oshandle_np(timerid[i]),timerid[i]);
  107. np = malloc(sizeof(struct entry)); /* Insert at the head. */
  108. np->code = timer_oshandle_np(timerid[i]);
  109. np->name=names[i];
  110. SLIST_INSERT_HEAD(&head, np, entries);
  111. /* Set values and start timer */
  112. struct itimerspec its;
  113. its.it_interval.tv_sec = 1 + i * 2;
  114. its.it_interval.tv_nsec = 0;
  115. its.it_value.tv_sec = its.it_interval.tv_sec;
  116. its.it_value.tv_nsec = 0;
  117. if (timer_settime(timerid[i], 0, &its, NULL)) {
  118. warn("timer_settime failed for %zu", i);
  119. }
  120. }
  121. printf("waiting...\n");
  122. for (; !spankme;) {
  123. pause();
  124. } //loop
  125. printf("\nbye.\n");
  126. for (size_t i = 0; i < nb_timers; ++i) {
  127. timer_delete(timerid[i]);
  128. }
  129. while (!SLIST_EMPTY(&head)) {
  130. np = SLIST_FIRST(&head);
  131. SLIST_REMOVE_HEAD(&head, entries);
  132. free(np->name);
  133. free(np);
  134. }
  135. }