C: SIGALRM - alarm to display message every second

Signal handlers are not supposed to contain "business logic" or make library calls such as printf. See C11 §7.1.4/4 and its footnote:

Thus, a signal handler cannot, in general, call standard library functions.

All the signal handler should do is set a flag to be acted upon by non-interrupt code, and unblock a waiting system call. This program runs correctly and does not risk crashing, even if some I/O or other functionality were added:

#include <signal.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>

volatile sig_atomic_t print_flag = false;

void handle_alarm( int sig ) {
    print_flag = true;
}

int main() {
    signal( SIGALRM, handle_alarm ); // Install handler first,
    alarm( 1 ); // before scheduling it to be called.
    for (;;) {
        sleep( 5 ); // Pretend to do something. Could also be read() or select().
        if ( print_flag ) {
            printf( "Hello\n" );
            print_flag = false;
            alarm( 1 ); // Reschedule.
        }
    }
}

Move the calls to signal and alarm to just before your loop. Calling alarm over and over at high speed keeps resetting the alarm to be in one second from that point, so you never reach the end of that second!

For example:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void display_message(int s) {
     printf("copyit: Still working...\n" );
     alarm(1);    //for every second
     signal(SIGALRM, display_message);
}

int main(void) {
    signal(SIGALRM, display_message);
    alarm(1);
    int n = 0;
    while (1) {
        ++n;
    }
    return 0;
}

Tags:

C

Alarm