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

Alceu R. de Freitas Jr. glasswalk3r em yahoo.com.br
Terça Março 15 05:15:35 PST 2005


Oi Daniel,

Eu ainda não testei as alterações que você sugeriu...
mas tenho algumas dúvidas que gostaria de sanar antes
de fazê-lo... acompanhe meus comentários abaixo...

--- Daniel Ruoso <daniel em ruoso.com> wrote:
> Beleza, dar erro significa o que? ter return code !=
> 0? não dar uma
> determinada resposta no STDOUT? dar uma determinada
> resposta no STDERR?
> isso que eu não entendi...

Na realidade, pra mim tanto faz se eu pego o erro via
sinal, retorno de código ou uma emissão telepática. Só
gostaria de saber se o processo filho fez o que tinha
que fazer.

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?
  
> 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.

> 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.
 
> 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?
  
> > 		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.
 
> > 			
> >   	    } 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.

> 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 ($?);

Mais uma vez obrigado pela ajuda.

[]'s


Alceu Rodrigues de Freitas Junior
--------------------------------------
glasswalk3r em yahoo.com.br
http://www.imortais.cjb.net
-----------------------------------------------------------------------
A well-used door needs no oil on its hinges.
A swift-flowing stream does not grow stagnant.
Neither sound nor thoughts can travel through a vacuum.
Software rots if not used.
These are great mysteries -- The Tao Of Programming, 5.1


	
	
		
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