Ciao, so che questo post dovrei metterlo nella sezione PERL e CGI, però il mio problema, come farò capire, è più di tipo...insomma, interazione con pipe che sono in generale nella programmazione, vabbè....passiamo ai fatti, cioè, al codice.
Il mio problema riguarda l'esecuzione di alcuni programmi in un mio software.
Cioè, ho fatto un webserver che esegue CGI.
Ho scritto due funzioni per eseguire CGI e spedirli al browser.
La prima funzione è questa:
codice:
#$exe è il programma da eseguire. es: C:/php/php.exe
# $getp i parametri da passare per argv
# $postd i parametri arrivati con il metodo POST da inviare all'STDIN
sub xopen {
my ($exe,$getp,$postd)=@_;
$getp="" unless defined $getp;
my ($writer, $reader,$pagina,$vecchioin); # Dichiaro le variabili
pipe($reader,$writer); # Creo una coppia di pipe per inviare i dati al processo tramite STDIN
$writer->autoflush(1); # Svuoto il canale
open $vecchioin, "<&", \*STDIN or return undef; # Mi salvo il ref del vecchio STDIN
open (STDIN, "<&",$reader) or return undef; # Sovrascrivo il ref di STDIN con la pipe
open (PROG, "$exe $getp |") or return undef; # Avvio il processo aprendo una pipe in lettura
close $reader; # Chiudo la pipe destinata all'altro processo.
print $writer $postd if defined $postd; # Invio i dati tramite la pipe all'altro processo
$pagina.=$_ while <PROG>; # Salvo in uno scalare il testo che l'altro processo produce su STDOUT
close PROG; # Il processo dovrebbe essere già chiuso a questo punto ma di prassi...
close $writer; # Chiudo la pipe, anche se funzionava quando la lasciavo aperto
open STDIN, "<&",$vecchioin or die "impossibile aprire STDIN $!\n" if $vecchioin; # Reimposto il vecchio STDIN :)
# Tutto è nuovamente come prima e torno quello che il processo ha prodotto :)
return $pagina;
}
La funzione cattura STDOUT stampato ad esempio dal file php.exe che esegue uno script.
Questa funzione va benissimo e riesco a vedere tutte le pagine senza grossi problemi. Il problema è però che il mio programma si blocca fino a che lo script php non è concluso.
QUindi ho pensato di aprire l'STDOUT e L'STDERR sullo socket in modo che eseguo il programma e penso alle altre richieste, così php.exe deve pensare lui ad inviare sullo socket.
codice:
# $sock è l'oggetto socket del client.
sub open_rep {
my ($exe, $getp, $postd, $sock)=@_;
$getp="" unless defined $getp;
my ($old_stderr, $old_stdout);
open $old_stdout, "<&", \*STDOUT or return undef;
open $old_stderr, "<&", \*STDERR or return undef;
open STDOUT, ">&", $sock or return undef;
open STDERR, ">&", $sock or return undef;
open (PROG, "| $exe $getp") or return undef;
print PROG $postd if defined $postd;
PROG->autoflush(1);
open STDERR, ">&",$old_stderr or die "impossibile aprire STDERR $!\n"; # Reimposto il vecchio STDIN :)
open STDOUT, ">&",$old_stdout or die "impossibile aprire STOUT $!\n"; # Reimposto il vecchio STDIN :)
return 1;
}
La funzione non fa altro che mettere STDOUT sullo socket. POi esegue php.exe, reimpostare i vecchi STDOUT e STDERR e uscire dalla funzione.
Il primo modo funziona.
Il secondo mi da dei problemi con explorer ma funziona se uso telnet.
Come faccio a capire perchè explorer non mi fa vedere la pagina anche se con telnet riesco a vederla perfettamente?
Grazie in anticipo.