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

Daniel Ruoso daniel em ruoso.com
Segunda Março 14 14:18:37 PST 2005


Em Seg, 2005-03-14 às 18:30, Alceu R. de Freitas Jr. escreveu:
> 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.

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...
 
> É simples, eu preciso saber se o processo filho
> conseguiu rodar o programa e se o programa que ele
> rodou foi executado com sucesso.

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.
 
> > > Eu tentei usar o esquema "eval { }; die $@ if
> > $@;",
> > > mas também não funciona.

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.

> > 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. :-)

Agora eu tenho certeza... você fez uma graaaaaaaande confusão. ;)
 
> 		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.

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

e de resto, para saber se o processo obteve sucesso você precisa ter um
critério para diferenciar o sucesso do erro. Tipo, se o programa termina
retornando um OK!, então você sabe que deu sucesso. Mas o mais provavel
é ele terminar com exit code 0 para ser sucesso (pelo menos isso é o
padrão no mundo Unix), então você precisa capturar o exit code do
processo filho. 

Para capturar o exit code de um processo filho, você deve utilizar o
waitpid e verificar o exit code na variável $?.

daniel





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