[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