Search code examples
csetitimer

How to use setitimer with SIGALRM in C


I'm trying to use setitimer to send out a SIGALRM, which in turns calls my handler function to print to stdout. I've been scouring the internet for hours now and there is simply no clear indication on how setitimer should be used. I've tried various combinations but none seem to work. In my code I'm using sockets and pthreads but I dont think its really relevant to the problem, as I'm trying to set an alarm via a signal, which would halt all threads anyway, so I'll leave that code out for simplicity.

void handle_alarm(int sig){

    printf("Printing Info\n");

}


int main(int argc, char**argv){

    struct itimerval it_val;
    signal(SIGALRM, handle_alarm);
    it_val.it_value.tv_sec = 1;
    it_val.it_value.tv_usec = 1000000;  
    it_val.it_interval = it_val.it_value;
    setitimer(ITIMER_REAL, &it_val, NULL);
    while(1){}

    return 0;

}

It should simply print to the terminal every second but it does not. Can anyone give me any advice?


Solution

  • Can anyone give me any advice?

    The kernel might! If system calls fail, the kernel reports back an error code. The libc will report an error happened and set errno appropriately. Thus change

    setitimer(ITIMER_REAL, &it_val, NULL);
    

    to

    if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) {
      perror("setitimer");
      exit(1);
    }
    

    and see what went wrong. The appropriate man page will contain a list of possible error codes and their reasons:

       EFAULT new_value, old_value, or curr_value is not valid a pointer.
    
       EINVAL which is not one of ITIMER_REAL, ITIMER_VIRTUAL, or
              ITIMER_PROF; or (since Linux 2.6.22) one of the tv_usec fields
              in the structure pointed to by new_value contains a value
              outside the range 0 to 999999.
    

    The fix is left as an exercise to the asker. Also don't get used to calling non-async-signal-safe functions from inside a signal handler!