[Cascavel-pm] como apanhar errors de processos filhos iniciados por IPC::Open3 ?

Alceu R. de Freitas Jr. glasswalk3r em yahoo.com.br
Segunda Março 14 13:30:08 PST 2005


--- Daniel Ruoso <daniel em ruoso.com> wrote:
> Em Seg, 2005-03-14 às 18:01, Alceu R. de Freitas Jr.
> escreveu:
> > O problema é que eu não estou conseguindo fazer o
> > processo filho me retornar algo, um sinal, uma
> > mensagem, qualquer coisa, quando ele executar algo
> que
> > dê algum problema.
> 
> Você diz quando ele morrer?

Se ele morre, eu ainda consigo pegar a falha do Open3,
porque tenho acesso a STDERR. O problema é quando o
child não morre, ele roda o programa, mas o programa
causa algum erro.
 
> > "open3() returns the process ID of the child
> process.
> > It doesn't return on failure: it just raises an
> > exception matching /^open3:/. However, exec
> failures
> > in the child are not detected. You'll have to trap
> > SIGPIPE yourself."
> 
> Ele quer dizer que ele não consegue diferenciar um
> erro de execução do
> processo filho de um erro do exec, só isso.

Na verdade, por si só o módulo não checa o processo
filho.
 
> O que exatamente você chama de retornar erro?
> SIGPIPE só quer dizer que
> o PIPE foi quebrado.

É simples, eu preciso saber se o processo filho
conseguiu rodar o programa e se o programa que ele
rodou foi executado com sucesso.
 
> > Eu tentei usar o esquema "eval { }; die $@ if
> $@;",
> > mas também não funciona.
> 
> Eval??? como você usaria eval?

Assim:

#!/usr/bin/perl
# test1.pl
use IPC::Open3;
$n = "\n";
open( OUTPUT, ">&STDOUT" ) or 
    die "Can't dup STDOUT to OUTPUT: $!$n";
open( OUTERR, ">&STDERR" ) or 
    die "Can't dup STDERR to OUTERR: $!$n";
eval { 
    $pid = open3("<&STDIN", \*OUTPUT, \*OUTERR, 'perl
return.pl') ;
    $val = waitpid(-1,0); # <--- added this line
};
$@ && die "ERROR: $@$n";
@results = <OUTPUT>;
@errors  = <OUTERR>;
close OUTPUT;
close OUTERR;
print "---pid$n";     print $pid . $n;
print "---\$?$n";     print $? . $n; # <--- prints
exit val
print "---results$n"; foreach(@results) { print $_ .
$n };
print "---errors$n";  foreach(@errors)  { print $_ .
$n };
---

Outro exemplo:
http://www.perlmonks.org/index.pl?node_id=151886

> Acho que você está fazendo uma graaaaaaaande
> confusão... o trecho que
> você acabou de citar se refere a uma chamada fork()
> e não exec(), muito
> menos open ou open3

Sim, fork depois exec()... acho que não expliquei
direito. O que quis dizer é que o filho deveria
executar apenas o comando que passo como parâmetro
para o Open3. Depois de algumas tentativas madrugada
adentro com eval () eu acabei chegando num resultado
cabalístico que o filho repetia a mensagem de erro do
pai (ou vice-versa, sei lá). Não faça perguntas
difíceis. :-)
 
> O fato de ser CGI não muda nada...
> é interessante você mandar o código, pq eu realmente
> não entendi qual é
> o problema.

Obrigado pela ajuda. Vou postar parte do código pq ele
é meio grande. Se quiser dar uma olhada geral, por
favor me avise que eu mando anexado.

[]'s

Alceu

---

sub cleanit {

    my $fileurl  = shift;
    my $filename = shift;

# untaint data
    $config{scannerpath}  =
clean_taint($config{scannerpath},'\w\.\/\-\_');
    $config{virusscanner} =
clean_taint($config{virusscanner},'\w');
    $config{viruscmd}     =
clean_taint($config{viruscmd},'\w\.\_\-\s');
    $config{downloads}    =
clean_taint($config{downloads},'\w\.\/\-\_');

    delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
    $ENV{PATH} = $config{scannerpath};
    
    print $viralator->p("$lang{wviruscan} $filename
$lang{takeawhile}");
    
    if (-e "$config{downloads}/$filename") {

		my $pid =
open3(\*TOCHILD,\*FROMCHILD,\*FROMCHILD,"$config{scannerpath}/$config{virusscanner}",$config{viruscmd},"$config{downloads}/$filename");
		
		unless ( defined($pid) ) {
			
			unlink "$config{downloads}/$filename" ||
error('error',"$lang{rm_error}","$lang{rm_error}:
$!");
			error('error',"An error ocurred when tring to scan
the downloaded file for virus:
$lang{fileremoved}","Viruscan error: $!",'noheader');
			
  	    } else {

			print '<BR>';
			
		    while(<FROMCHILD>) {

               if ($_ =~ /^open3\:.*failed/) {
	
				   unlink "$config{downloads}/$filename" ||
error('error',"$lang{rm_error}","$lang{rm_error}:
$!");
				   error('error',"An error ocurred when tring to
scan the downloaded file for virus:
$lang{fileremoved}",
				   'Viruscan error: open3 failed','noheader');

			   }

               if ($_ =~ /$config{alert}/o) {
                
		           unlink "$config{downloads}/$filename" ||
error('error',"$lang{rm_error}","$lang{rm_error}:
$!");
                   error('warning',"$lang{vfounddl}:
$lang{fileremoved}.","Virus found in file requested by
$client");
            
		       } else {
# print viruscanner information about the file scanned
                   $config{scannersummary} eq 'true' ?
print '<br>'.$_ : print '.';
#end of if block				 
               }
#end of while block	    
	       }
#end of if block	   
       }

       close(TOCHILD) or die "$!\n";
       close(FROMCHILD) or die "$!\n";
    
       waitpid $pid, 0;
    
    } else {
    
        error('warning',$lang{no_resource},'No file');
#end of if block    
    }




	
	
		
Yahoo! Mail - Com 250MB de espaço. Abra sua conta! http://mail.yahoo.com.br/


Mais detalhes sobre a lista de discussão Cascavel-pm