Ctrl-C mangé par getchar ()

Je cherche une solution à mon problème depuis longtemps maintenant, c’est pourquoi je me tourne vers vous:

Considérez ce morceau de code:

static char done = 0; static void sigHandler(void) { done = 1; } int user_input() { return (getchar() == 'q') ? 0 : 1; } int main(void) { signal(SIGTERM, sigHandler); signal(SIGINT, sigHandler); while (user_input() != 0 && !done) usleep(1000); printf("exiting\n"); return 0; } 

Comportement attendu: Le programme se termine lorsque l’utilisateur entre q puis entre. Si vous appuyez sur CTRL + C , la fonction sigHandler intercepte l’atsortingbut “done” à 1 et quitte le programme.

Comportement observé: Le caractère CTRL + C est mangé par l’appel getchar () et la fonction sigHandler n’est jamais exécutée. Lorsque vous appuyez sur CTRL + C et que vous entrez, la fonction sigHandler est appelée et le programme se ferme.

Est-ce que quelqu’un avec plus d’expérience et de connaissance pourrait m’aider dans ce domaine?

Merci pour votre consortingbution 🙂

Il existe un moyen d’interrompre l’appel sans avoir recours à des hacks déplaisants (contrairement à ce que Paul R a dit). Vous devez utiliser sigaction() avec sa_flags défini sur 0 au lieu de signal() .

En outre, le manuel signal (2) dit:

Evitez son utilisation : utilisez sigaction (2) à la place.

 #include  #include  #include  #include  static char done = 0; static void sigHandler(int signum) { done = 1; } int user_input() { return (getchar() == 'q') ? 0 : 1; } int main(void) { struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction)); sa.sa_handler = sigHandler; sa.sa_flags = 0;// not SA_RESTART!; sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); while (user_input() != 0 && !done) usleep(1000); printf("exiting\n"); return 0; } 

Normalement, après avoir attrapé et manipulé un signal, la plupart des appels système (je ne suis pas sûr de tous) seront redémarrés. Ainsi, après avoir traité le signal sigint, votre fonction getchar continuera comme si de rien n’était. Vous pouvez modifier ce comportement en appelant sigaction avec sa_flags=0 .

De cette façon, après avoir traité SIGINT, getchar renverra -1 et errno aura la valeur “Appel système interrompu” (je ne me souviens plus du nom de la constante pour le moment).

Vous devrez également réécrire votre fonction user_input () pour gérer le cas lorsque vous retournez -1.

Le code fonctionne effectivement comme prévu – vous ne testez pas l’indicateur done avant que vous ne user_input() de user_input() , c’est pourquoi vous devez entrer un caractère supplémentaire après le contrôle-C.

Si vous voulez abandonner l’appel à getchar quand vous obtenez un contrôle-C, vous devrez probablement faire quelque chose de moche, par exemple, utilisez setjmp / longjmp .

Le caractère Ctrl-C est mangé par l’appel getchar getchar() et la fonction sigHandler n’est jamais exécutée.

Ctrl-C n’est pas mangé par getchar ; Il en résulte qu’un signal est délivré et que sigHandler est exécuté. Cela établit et retourne. Ce n’est getchar est appelé, qui mange la nouvelle ligne et que , par la suite , done est vérifié pour que le programme se termine.

Btw., Un gestionnaire de signal prend un argument int , pas void .