#define _POSIX_C_SOURCE 1 #include #include #include #include #include #include "hms.h" #define NOMBRE_D_INTERRUPTIONS 5 #define DELAI 15 static sigjmp_buf avant_la_boucle; static volatile sig_atomic_t action_afficher = 0; static volatile sig_atomic_t action_sortie = 0; static volatile sig_atomic_t action_sonnerie = 0; static volatile sig_atomic_t ne_pas_traiter_sigint = 0; static long compteur = 0; static void interruption_interactive(int signal); static void sonnerie(int signal); static void afficher_heure(void); int main(void) { struct sigaction action; sigset_t bloquer_sigint; sigset_t bloquer_sigint_et_alarm; sigset_t sauvegarde_du_masque; sigemptyset(&bloquer_sigint); sigaddset(&bloquer_sigint, SIGINT); bloquer_sigint_et_alarm = bloquer_sigint; sigaddset(&bloquer_sigint_et_alarm, SIGALRM); action.sa_handler = interruption_interactive; action.sa_mask = bloquer_sigint; sigaction(SIGINT, &action, NULL); action.sa_handler = sonnerie; action.sa_mask = bloquer_sigint_et_alarm; sigaction(SIGALRM, &action, NULL); alarm(DELAI); if (sigsetjmp(avant_la_boucle, 1) == 0) { for (;;) { compteur += 10; /* Début de la section critique */ sigprocmask(SIG_SETMASK, &bloquer_sigint_et_alarm, &sauvegarde_du_masque); if (action_afficher) { sigset_t signaux_pendants; sigprocmask(SIG_SETMASK, &bloquer_sigint, NULL); sleep(1); sigprocmask(SIG_SETMASK, &bloquer_sigint_et_alarm, NULL); sigpending(&signaux_pendants); if (sigismember(&signaux_pendants, SIGINT)) { printf("Arrêt du programme (o/n) : "); for (;;) { switch (getchar()) { case EOF: case 'o': siglongjmp(avant_la_boucle, 1); case 'n': goto fin_de_boucle; } } fin_de_boucle: ne_pas_traiter_sigint = 1; ; } afficher_heure(); printf(" : %ld\n", compteur); action_afficher = 0; } if (action_sortie) break; if (action_sonnerie) { afficher_heure(); printf(" -> Expiration de la minuterie\n"); siglongjmp(avant_la_boucle, 1); } sigprocmask(SIG_SETMASK, &sauvegarde_du_masque, NULL); /* Fin de la section critique */ } } else { printf("Exécution du programme interrompue\n"); return EXIT_FAILURE; } printf("Terminaison du programme\n"); return EXIT_SUCCESS; } static void afficher_heure(void) { int heures; int minutes; int secondes; hms(&heures, &minutes, &secondes); printf("[%02d:%02d:%02d]", heures, minutes, secondes); } static void interruption_interactive(int signal) { static int n = 0; if (ne_pas_traiter_sigint) ne_pas_traiter_sigint = 0; else { action_afficher = 1; if (++n == NOMBRE_D_INTERRUPTIONS) action_sortie = 1; } } static void sonnerie(int signal) { action_sonnerie = 1; }