Deuxième appel dans sighandler – pour quoi faire?

cemment, j’ai trouvé du code qui utilise le signal :

  286 static void sighandler( int signum ) 287 { 288 alarmed = 1; 289 signal( signum, sighandler ); 290 } 291 292 void set_alarm( int seconds ) 293 { 294 alarmed = 0; 295 signal( SIGALRM, sighandler ); 296 alarm( seconds ); 297 } 

J’ai quelques problèmes à comprendre pourquoi dois-je appeler le signal 2 fois, en particulier, pourquoi dois-je appeler le signal dans sighandler ? Je sais ce que le code ci-dessus fait mais ne comprend pas pourquoi ai-je besoin d’appeler le signal 2 fois.

Traitement des signaux

L’appel au signal établit la gestion du signal pour une seule occurrence du signal. Avant d’appeler la fonction de traitement du signal, la bibliothèque réinitialise le signal afin que l’action par défaut soit effectuée si le même signal se reproduit . La réinitialisation de la gestion du signal permet d’éviter une boucle infinie si, par exemple, une action effectuée dans le gestionnaire de signaux génère à nouveau le même signal. Si vous souhaitez que votre gestionnaire soit utilisé pour un signal chaque fois qu’il se produit, vous devez appeler signal dans le gestionnaire pour le rétablir. Vous devez faire preuve de prudence en rétablissant la gestion du signal. Par exemple, si vous rétablissez continuellement la gestion SIGINT, vous risquez de ne plus pouvoir interrompre et mettre fin à votre programme.

La fonction signal() définit uniquement le traitement du prochain signal reçu, après quoi le traitement par défaut est rétabli . Il est donc nécessaire que le gestionnaire de signal() appelle signal() si le programme doit continuer à gérer les signaux à l’aide d’un gestionnaire autre que celui par défaut.

(1) Appeler le signal deux fois ou plus n’est pas inhabituel. Il suffit de configurer deux gestionnaires pour 2 signaux différents.

(2) Les anciens systèmes Unix utilisés pour réinitialiser une disposition de signaux par défaut après l’appel d’un gestionnaire. Ce code rétablit le gestionnaire.

La page de man (2) signal GNU man (2) signal contient quelques paragraphes consacrés à cela dans la section “portabilité”. En fait une des nombreuses raisons d’utiliser la sigaction .

Il existe des systèmes où, si signal() est appelé avec une fonction, le gestionnaire de signaux est réinitialisé après le premier signal capturé (je n’ai pas découvert à la volée s’il était défini ainsi). C’est la raison pour laquelle signal() est appelé à nouveau dans le gestionnaire de signaux.