Comment append du code au gestionnaire de signal standard?

J’ai une application C fonctionnant sous Linux où j’ai besoin d’append du code au gestionnaire de signal standard. L’idée était de configurer mon gestionnaire en enregistrant le pointeur sur le standard et d’appeler le gestionnaire enregistré à partir de mon code. Malheureusement, ni signal () ni sigaction () ne renvoient de pointeur vers le gestionnaire standard. Les deux retournent NULL à la place. Existe-t-il un moyen de gérer sur mesure et de poursuivre la gestion standard sans supprimer le gestionnaire personnalisé et renvoyer le même signal?

Il n’y a pas de “gestionnaire de signal standard”; à la place, le kernel effectue une action par défaut lorsqu’un signal n’est pas géré. Si vous voulez faire quelque chose lorsque le signal est reçu, puis revenir à l’action par défaut, vous pouvez procéder comme suit à la fin de votre gestionnaire de signal:

sigset_t set; signal(sig, SIG_DFL); raise(sig); sigemptyset(&set); sigaddset(&set, sig); sigprocmask(SIG_UNBLOCK, &set, 0); 

Cela suppose que vous avez utilisé sigaction pour installer votre gestionnaire de signal et que vous n’avez pas spécifié les SA_NODEFER ou SA_RESETHAND . Il est également possible de réaliser ce que vous voulez en utilisant ces drapeaux et simplement en appelant raise , mais les conditions de course sont mauvaises si le signal est délivré deux fois de suite, vous ne devriez donc pas le faire; utilisez plutôt la méthode que j’ai suggérée.

Edit: En fait, vous n’aurez pas à faire quoi que ce soit du masque de signal, car le fait de revenir du gestionnaire de signaux restaurera l’ancien masque de signal. Juste cela devrait fonctionner:

 signal(sig, SIG_DFL); raise(sig); return; 

Lorsque l’appel à signal () ou à sigaction () renvoie NULL, cela implique SIG_DFL (c’est-à-dire un gestionnaire de signal par défaut).

Si vous utilisez signal (), le gestionnaire est censé être réinitialisé lorsque le gestionnaire est appelé, vous pouvez émettre la dernière ligne du gestionnaire de signaux en levée (SIGNAL) et il doit appeler le gestionnaire par défaut.

Si vous utilisez sigaction (), vous devez passer SA_RESETHAND comme l’un des indicateurs, ce qui vous permettra d’utiliser l’appel de relance (SIGNAL) dans ce gestionnaire.

La grande majorité des gestionnaires de signaux par défaut mettront fin à l’application. Ce remplacement «ponctuel» fonctionnera donc. Vous pouvez append un appel sigaction () après l’appel de relance pour stocker à nouveau le nouveau gestionnaire, par exemple

 void sighandler(int signum) { // Do my stuff raise(signup); signal(signum, sighandler); }