title: Send signal at specific time in linux C
body: <p>I'm writing a C program for raspberry and I need to do something at specific time (in my case at midnight).
  I don't want to check the time every time like "polling" but I would like to generate an interrupt software using signals and lets the handler to do his work.
  In this example I am able to set the firs interrupt but after TIMER_FREQUENCY it not send next one so I've created a new timer into the handler to have continuously a new timer that will expires after TIMER_FREQUENCY seconds.</p>
  
  <p>Example </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;signal.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;time.h&gt;
  #include &lt;string.h&gt;
  #include &lt;math.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;assert.h&gt;
  #include &lt;sys/wait.h&gt;
  
  /* 3h = 3 * 60 * 60*/
  #define TIMER_FREQUENCY 10800
  
  static int count;
  
  void timer_expired(int sig)
  {
      /* Set new timer for next interrupt - 3 hours*/
      struct sigaction act;
      clockid_t clock_id;
      timer_t timer_id;
      struct sigevent clock_sig_event;
      struct itimerspec timer_value;
      int ret;
  
      /* timestamp */
      time_t now;
      struct tm* tm_info;
  
      char *temp=(char*)malloc(20*sizeof(char));
  
      /* Register new action for SIGUSR1 */
      memset(&amp;act, 0, sizeof(struct sigaction));
      act.sa_handler =  timer_expired;
      ret = sigaction(SIGUSR1, &amp;act, NULL);
      assert(ret == 0);
  
      clock_id = CLOCK_MONOTONIC;
      memset(&amp;clock_sig_event, 0, sizeof( struct sigevent));
      clock_sig_event.sigev_notify = SIGEV_SIGNAL;
      clock_sig_event.sigev_signo = SIGUSR1;
      clock_sig_event.sigev_notify_attributes = NULL;
      /* Creating process interval timer */
      ret = timer_create(clock_id, &amp;clock_sig_event, &amp;timer_id);
      assert(ret == 0);
  
      /* setitng timer interval values */
      timer_value.it_interval.tv_sec = TIMER_FREQUENCY;
      timer_value.it_interval.tv_nsec = 0;
  
      /* setting timer initial expiration values*/
      memset(&amp;timer_value, 0, sizeof(struct itimerspec));
      timer_value.it_value.tv_sec = TIMER_FREQUENCY;
      timer_value.it_value.tv_nsec = 0;
  
      /* Prendo l'orario attuale */
      time(&amp;now);
      tm_info=localtime(&amp;now);
      strftime(temp,20,"%H:%M:%S",tm_info);
  
      count++;
  
      // use this handler
      printf("Ricevuto %d° segnale alle ore: %s \n",count,temp);
  
      printf("Attendo segnale fra 3 ore...\n");
  
      /* Create timer */
      ret = timer_settime(timer_id, 0, &amp;timer_value, NULL);
      assert(ret == 0);
  
  }
  
  int main(void)
  {
      struct sigaction act;
      clockid_t clock_id;
      timer_t timer_id;
      struct sigevent clock_sig_event;
      struct itimerspec timer_value;
      int ret;
  
  
      char *giorno=(char*)malloc(3*sizeof(char));
      char *ora=(char*)malloc(3*sizeof(char));
      char *minuti=(char*)malloc(3*sizeof(char));
      char *secondi=(char*)malloc(3*sizeof(char));
  
      time_t fine, now;
      struct tm* tm_info;
  
      char *temp=(char*)malloc(20*sizeof(char));
  
      double seconds=0.0;
      long int intervallo=0;
      float ore=0.0;
  
      count=0;
  
      /* Here i get seconds from now until 23:59:59 to set first timer */
  
      time(&amp;now);
      time(&amp;fine);
      tm_info=localtime(&amp;now);
  
      strftime(giorno,3,"%d",tm_info);
      strftime(ora,3,"%H",tm_info);
      strftime(minuti,3,"%M",tm_info);
      strftime(secondi,3,"%S",tm_info);
  
      sprintf(temp,"%d:%d:%d",23,59,59);
      strptime(temp,"%H:%M:%S",tm_info);
      fine=mktime(tm_info);
  
      time(&amp;now);
  
      // get seconds until fine
      seconds=difftime(fine,now);
  
      intervallo=(long int)seconds;
      ore=intervallo/3600;
      printf("Secondi restanti fino alle 23:59:59 : %lis = %f ore \n",intervallo, ore);
  
      count=0;
      /* Register new action for SIGUSR1 */
      memset(&amp;act, 0, sizeof(struct sigaction));
      act.sa_handler =  timer_expired;
      ret = sigaction(SIGUSR1, &amp;act, NULL);
      assert(ret == 0);
  
      clock_id = CLOCK_MONOTONIC;
      memset(&amp;clock_sig_event, 0, sizeof( struct sigevent));
      clock_sig_event.sigev_notify = SIGEV_SIGNAL;
      clock_sig_event.sigev_signo = SIGUSR1;
      clock_sig_event.sigev_notify_attributes = NULL;
  
      /* Creating process interval timer */
      ret = timer_create(clock_id, &amp;clock_sig_event, &amp;timer_id);
      assert(ret == 0);
  
      /* setitng timer interval values */
      timer_value.it_interval.tv_sec = intervallo;
      timer_value.it_interval.tv_nsec = 0;
  
      /* setting timer initial expiration values*/
      memset(&amp;timer_value, 0, sizeof(struct itimerspec));
      timer_value.it_value.tv_sec = intervallo;
      timer_value.it_value.tv_nsec = 0;
  
      /* Create timer */
      ret = timer_settime(timer_id, 0, &amp;timer_value, NULL);
      assert(ret == 0);
  
      /* Now we have a timer with following features:
       * It will expire after 24 hours and excute fucntion timer_expired
       * upon expiration */
  
      /* I've used sleep into while because I just want to wait and handle the interrupt using less CPU as possible */
      while(1){
          sleep(500);  
      }
  
      /*
       * Do something here
       *
       * To test, sleep()  for 5 sec and set timer expiry as 1 sec i.e.
       * TIMER_FREQUENCY as 1.
       * In this case first timer will expire after 1 sec and sleep will
       * come out, also timer_expired() will be executed. Later time will expire after every 1 sec.
       *
       * We can also use SIGEV_THREAD instead of SIGEV_SIGNAL in clock_sig_event.sigev_notify
       * while creating timer_id using timer_create().In that case we need to check for other parameter
       * as well.
       */
  
      exit(EXIT_SUCCESS);
  }
  </code></pre>
  
  <p>This is the output:</p>
  
  <pre><code>pi@raspberrypi:~/Desktop/TastoW/rtc $ ./rtc
  Secondi restanti fino alle 23:59:59 : 22200s = 6.000000 ore 
  Ricevuto 1° segnale alle ore: 23:59:59 
  Attendo segnale fra 3 ore...
  Ricevuto 2° segnale alle ore: 02:59:59 
  Attendo segnale fra 3 ore...
  Ricevuto 3° segnale alle ore: 05:59:59 
  Attendo segnale fra 3 ore...
  Ricevuto 4° segnale alle ore: 08:59:59 
  Attendo segnale fra 3 ore...
  </code></pre>