Comment redirect le signal vers le processus enfant à partir du processus parent?

J’essaie de comprendre les processus en C. Je veux actuellement créer une structure de type shell qui, après avoir appuyé sur un raccourci tel que Ctrl + C ou Ctrl + Z, va tuer tous ses sous-processus mais restra en vie. Mon code ressemble à ceci:

#include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  pid_t pid; void send_signal(int signum){ kill(pid, signum); } void init_signals(){ signal(SIGINT, send_signal); signal(SIGTSTP, send_signal); } int main(){ init_signals(); pid = fork(); if(pid > 0){ //Parent Process wait(NULL); } else { // Child Process while(1){ usleep(300000); } } return 0; } 

Le problème ici est que, lorsque j’appuie sur Ctrl + C, le parent le redirige vers l’enfant et le tue, mais lorsque j’appuie sur Ctrl + Z (même si le processus enfant est arrêté), le parent est toujours en wait(NULL) . Des suggestions sur la façon de résoudre ce problème?

Vous pouvez vérifier ici comment utiliser wait in C. Longue histoire courte:

L’appel système wait met le processus en veille et attend la fin d’un processus enfant. Il remplit ensuite l’argument avec le code de sortie du processus enfant (si l’argument n’est pas NULL).

wait n’est pas signalé jusqu’à la fin du processus enfant. Il suffit donc de le laisser dormir pour qu’il ne poursuive pas le processus principal. Si vous souhaitez une configuration dans laquelle le processus principal fonctionne toujours, de même que l’enfant (y compris lorsqu’il dort!), Vous ne pouvez pas attendre l’enfant.

Cela n’aurait aucun sens pour un shell non plus – il est toujours actif en arrière-plan. Au lieu de cela, vous avez besoin d’un meilleur gestionnaire sur main – comme attendre une condition. De cette façon, lorsque vous faites endormir un enfant, vous pouvez signaler le problème et continuer.

Outre la solution disponible à l’ adresse https://stackoverflow.com/a/49346549/5694959, j’aimerais suggérer une solution supplémentaire pour le traitement des signaux du processus parent uniquement. Cette méthode permet au parent d’exécuter le gestionnaire de signaux et d’effectuer les actions par défaut processus. Utilisez waitpid() pour obtenir le statut d’enfant.

waitpid (pid, NULL, WUNTRACED);

Maintenant, le parent reprendra son exécution lorsque le processus enfant changera d’état, c’est-à-dire qu’il sera terminé ou arrêté.

Mettez à jour votre code comme suit:

 #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  pid_t pid; void send_signal(int signum){ kill(pid, signum); } void init_signals(){ signal(SIGINT, send_signal); signal(SIGTSTP, send_signal); } int main(){ pid = fork(); if(pid > 0){ //Parent Process init_signals(); waitpid(pid, NULL, WUNTRACED); printf("I think this is what you are expecting...\n"); } else { // Child Process while(1){ usleep(300000); } } return 0; } 

Gardez simplement à l’esprit que vous devez vous assurer que le processus parent a traité le signal avant d’appuyer sur ctrl + c ou ctrl + z, sinon l’action par défaut du signal sera également exécutée pour le parent.