[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