(Courriels de diversion: <presentez@orthographieraient-interviendrions.com> <abuserais@cingleront-desires.com> <pauperisons@renseignant-reelirions.com> <ressassait@ânonnent-necessaire.com> <humecterait@flouerais-illusionnes.com> <inversaient@contribuons-entravait.com> <racheterent@crasse-vissais.com> <confrontez@croquiez-deferente.com> <denicheras@petarader-predilections.com> <mi-voix@thesauriserais-absente.com> )
Le 5 Jan, Arnaud Rolly écrit : > switch(pid=fork()) > { > case -1: > /* error */ > error_show("Impossible to launch the necessary program."); > case 0: > /* soon process */ > system(exec_command); Quand system retourne, le fils exécute le code qui suit : tu voulais sans doute mettre un exit quelque part par ici pour terminer le fils. > default: > /* father process */ > signal(SIGCHLD,end_fork); Tu devrais installer le gestionnaire de signal _avant_ de faire le fork : rien ne te garantit en effet que le séquence des événements ne va pas être : - fils se termine ; - père installe le gestionnaire. > Le problème, c'est que lorsque je ferme le programme lancé avec le system(...), > tout plante en bautée, avec en prime un message X : > Xlib: unexpected async reply (sequence 0x1598)! > FIN! Comme FIN! s'affiche, les choses se passent dans le bon ordre. Ton problème est caractéristique d'un double accès au serveur X sur la même connexion. Comme il te manque un exit dans le fils, tu dois exécuter le code que tu aurais voulu limiter au père, en particulier le code d'interaction avec l'utilisateur. C'est là qu'il faut se rappeler qu'après le fork, le canal de communication avec le serveur X est partagé entre le père et le fils. Ils se retrouvent en conccurrence pour lq lecture de ce qu'envoie le serveur, et sont susceptibles de mêler ce qu'ils lui envoient. Pas top. > Le man de signal me donne : > void (*signal(int signum, void (*handler)(int)))(int); > Heu... Je suis pas sur de l'utilisation que j'en ai faite. Pour signal, c'est bien. Comme tu as l'air de te moquer du code de retour du programme lancé, tu as une autre technique pour éviter les zombies : il te suffit d'utiliser le mécanisme de gestion des orphelins du sytème (que j'ai évoqué dans un courrier précédent). L'idée est de faire un fork, puis dans le fils de faire un autre fork. Le fils n'attend pas le petit fils (qui se retrouve orphelin et est donc adopté par le processus de pid 1). Le père fait un wait, qui ne bloque pas longtemps puisque le fils meurt de suite. 0 zombie, donc, puisque tous les morts sont attendus. Enfin, il faut se souvenir que la fonction system intervient aussi là-dedans : pour ce qui nous intéresse, on peut schématiser son code comme suit : int system(const char *cmd) { int wstatus; switch (fork() { case 0: execl("/bin/sh", "/bin/sh", "-c", cmd, NULL); return -1; case -1: return -1; default: wait(&status); return status; } } -- Marc Thirion | Toulouse, France Un Travail pour Chacun : http://www.multimania.com/untravailchacun/ Marc.Thirion@ISOscope.com : http://www.ISOscope.com/Pérennité des logiciels et des systèmes --------------------------------------------------------------------- Aide sur la liste: <URL:mailto:linux-31-help@savage.iut-blagnac.fr>Le CULTe sur le web: <URL:http://savage.iut-blagnac.fr/>