Bonjour tout le monde,
Je développe actuellement une application, qui, une fois lancée, permet de lancer à son tour n'importe quelle commande et de rediriger son STDOUT/STDIN sur un serveur socket (créé avec IO::Socket::INET)
Une fois le socket en place, et la commande lancée (avec open2), quand quelqu'un se connecte au serveur, il voit comme si il était devant l'écran et il peut intéragir avec.
En fait ca ressemble à netcat quand on tape : netcat -l -p port -e "commande" (il me semble)
Je ne peux pas vous montrer tout le code, pour des raisons de confidentialité
Donc voilà, en console locale, je peux taper "Quit", ce qui fait normalement se fermer tout le bordel, mais je peux voir (avec ps) que la commande lancée par open2 est toujours la (un zombie quoi...) alors qu'en appuyant sur CTRL+C, ca fonctionne, pas de zombie !
J'ai beaucoup cherché sur google et ici, dans la FAQ et les sources, mais je ne trouve pas la solution... c'est surement tout simple !
J'ai mis un hook sur les signaux :
le $LOOP est testé dans une boucle while($LOOP) qui est le coeur du programme, si elle vient à 0 alors le programme se termine !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 $SIG{CHLD} = \&mort; $SIG{__WARN__} = 'IGNORE'; $SIG{__DIE__} = sub { $SIG{__DIE__}='IGNORE'; $LOOP = 0; }; $SIG{HUP} = $SIG{INT} = $SIG{TERM} = sub { my $sig = shift; $SIG{$sig} = 'IGNORE'; $LOOP = 0; }; sub mort() { my $stiff; while (($stiff = waitpid(-1, WNOHANG)) > 0) { warn ("Enfant $stiff killé -- status $?"); } $SIG{CHLD} = \&mort; }
Il y'a un select dans cette boucle, j'y ai mis le handle en lecture du open2 et tous les handles des clients... ainsi que \*STDIN (pour le local)
voilà le code quand on tape "Quit" en local :
et après la boucle while, il y'a ca :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 $LOOP = 0; # Part de la boucle while...
Je crois que j'ai mis le principal, j'espère avoir bien expliqué
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 print "Quitte le programme...\n"; $select->remove($READ); # $READ va avec le open2 delAllClients(); # Efface tout le monde du select et ferme les sockets clients close $READ; close $WRITE; #kill TERM => $APPPID; #waitpid -1,WNOHANG; #wait; close $TCPDAEMON; # Ferme le démon TCP print "Fait.\n";
Merci d'avance,
Yann
Partager