sleep.c

#include <stdio.h>

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

#include "utils.h"

static volatile int alarm_set = 0;
static void ring_alarm(int signo)
{
    alarm_set = 0;
}

void my_sleep(int time)
{
    // One shot handler
    struct sigaction sa = {
        sa.sa_handler = ring_alarm,
        sa.sa_flags = SA_RESETHAND,
    };
    sigemptyset(&sa.sa_mask);
    struct sigaction old;
    exit_if(
            sigaction(SIGALRM, &sa, &old) == -1,
            "Can't install sig handler");

    // On ignore tous les signaux sauf SIGALARM
    // RQ: cette partie est verbeuse, car on ne veut QUE SIGALRM
    // pour un comportement plus simple, pause fait très bien le job.
    // voire on pourrait se passer de `alarm_set`
    sigset_t mask;
    sigfillset(&mask);
    sigdelset(&mask, SIGALRM);
    alarm_set = 1;
    alarm(time);
    while(alarm_set)
        sigsuspend(&mask);

    // On restaure l'ancien handler
    exit_if(
            sigaction(SIGALRM, &old, NULL) == -1,
            "Can't restore sig handler");
}

int main(int argc, char *argv[])
{
    printf("pid: %d\n", getpid());
    my_sleep(100);
    printf("Il est l'or, mon seignor\n");
    return 0;
}