Comment puis-je obtenir par programme le comportement par défaut de sigterm dans un gestionnaire de signal personnalisé?

Sur la base du man -S 7 signal , lorsqu’un programme qui n’a pas défini de gestionnaire de signal reçoit SIGTERM , l’action par défaut est Term .

J’enregistre un gestionnaire de signal personnalisé pour SIGTERM , mais je souhaite que l’instruction finale (après un nettoyage spécifique) dans mon gestionnaire personnalisé soit un appel de fonction réalisant exactement le même effet que Term .

Quelle est la fonction correcte d’appeler ici?

J’ai essayé exit(0) , mais cela provoque l’appel des destructeurs d’objects statiquement initialisés, ce qui ne correspond pas au comportement de Term . J’ai également essayé d’ abort() , et cela provoque un vidage de mémoire.

Dans l’exemple suivant, j’utilise la durée de vie des objects alloués statiquement à titre d’ exemple , mais ma question est plus large que la durée de vie des objects alloués de manière statique.

 #include  #include  #include  struct Foo{ ~Foo() { fprintf(stderr, "Dying!\n"); } Foo() { fprintf(stderr, "Constructing!\n"); } }; Foo foo; void sig_handler(int signo) { // exit(0); // abort(); } int main(){ // signal(SIGTERM, sig_handler); while(1); } 

Voici différents comportements:

  1. Le code tel quel sera imprimé Constructing! mais pas en Dying! si SIGTERM est reçu.
  2. Lorsque la ligne de //signal sera commentée et que exit(0) sera commenté, le code imprimera les deux Constructing! et Dying!
  3. Lorsque exit(0) est commenté et que abort() est commenté, le programme affichera la Constructing! suivi par Aborted (core dumped) .

Pour poser ma question d’une autre manière, je veux savoir ce que je dois mettre dans le corps de signal_handler afin d’imiter le comportement 1 à tous les signal_handler (pas seulement le résultat que j’ai montré).

 signal(SIGTERM, SIG_DFL); kill(getpid(), SIGTERM); 

Il n’y a pas d’appel de fonction, car la terminaison sur les signaux est gérée par le kernel, pas le processus utilisateur, mais cela restaure le gestionnaire par défaut, puis envoie un signal à vous, ce qui détruit le processus.

Vous pouvez appeler _exit place de exit , qui doit quitter le processus sans exécuter de destructeurs globaux.