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

Daniel Ruoso daniel em ruoso.com
Terça Março 15 10:37:51 PST 2005


Em Ter, 2005-03-15 às 10:15, Alceu R. de Freitas Jr. escreveu:
> Se eu estivesse usando 'system' eu faria isso com
> retorno de código. Com 'open()' também dá pra fazer
> isso. Pelo que entendi de SIGPIPE deveria acusar algum
> erro, visto que IPC::Open3 abre pipes para o processo
> filho... ou não?

Não... quando o processo morre (o que *sempre* vai acontecer), o SIGPIPE
vai ser lançado avisando que os pipes para o processo não são mais
válidos.
  
> > Primeiro de tudo você tem que estabelecer um
> > parâmetro para detectar
> > quando o programa falha, isso pode ser feito por uma
> > mensagem de erro,
> > pela ausência de uma mensagem de sucesso ou por um
> > exit code específico.
> Por código seria melhor, visto que não posso prever
> com eficácia mensagens de erro.

Perfeito.

> > Ah sim, você realmente deve usar o eval para
> > capturar o erro do open3,
> > você deve verificar se o $@ contém o "open3:", e não
> > o STDERR do
> > processo que você chamou.
> Ué... a mensagem de erro (quando aparece) está na
> leitura do STDERR do processo filho... eu nem chequei
> $@ para apanhar isso e nem usei eval.

Então eu entendi errado, mas o que a documentação parece dizer é que o
open3 vai fazer um die com /open3: .+failed.+/ como mensagem. Você tem
certeza que ele lançou no processo filho? ou é pq vc tá jogando o STDERR
do processo filho para o STDERR do teu processo?

> > Agora eu tenho certeza... você fez uma graaaaaaaande
> > confusão. ;)
> Gostaria de clarear as idéias. perldoc perlipc não
> ajuda muito. Alguma outra referência?

perldoc POSIX

> > > 		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');
> > 
> > Essa parte está ok.
> Mas eu não usei eval.
 
O eval é opcional.

> > > 			
> > >   	    } else {
> > > 
> > > 			print '<BR>';
> > > 			
> > > 		    while(<FROMCHILD>) {
> > > 
> > >                if ($_ =~ /^open3\:.*failed/) {
> > 
> > a verificação do open3 failed deve ser no $@ e você
> > deve chamar o open3
> > dentro de um eval para poder capturar isso.
> Como eu disse, esse trecho do código me retorna erro,
> se, por exemplo, o parâmetro de comando do open3
> aponta para um programa que não existe, como
> 
> open3($entrada,$erro,$saida,zabumba);
> 
> Considerando que não tenha nada executável no PATH
> chamado "zabumba", meu script retorna o erro iniciando
> em "open3" exatamente no trecho apresentado acima.

Então eu entendi errado mesmo... ;)

> > Para capturar o exit code de um processo filho, você
> > deve utilizar o
> > waitpid e verificar o exit code na variável $?.
> Seria isso? (não testei):
> 
> waitpid $pid, 0;
> 
> die "erro com processo filho" unless ($?);

A princípio, sim.

> Mais uma vez obrigado pela ajuda.

q nada,

daniel



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