rastoboy has asked for the wisdom of the Perl Monks concerning the following question:

Hello Brothers,

I'm quite new to doing IPC work in Perl, and I'm having a devil of a time handling errors. For example, I do this, using IPC::Open3:

my $pid = open3( $wtr, $rdr, $err, $httpd, '-v' ); my ($version, $builtondate) = <$rdr>;
and that works just fine--when the binary is correctly specified in $httpd. If I move the binary out of the way for testing so that the call will fail, I get errors spewed to my terminal about undefined variables and such, which I would expect.

So I would like to trap the failure. What I understood from the cpan page for IPC::Open3 is that errors would be written to the $err filehand however if I do this:

print readline $err;
when I've moved the httpd binary out of the way, I get this error from my script:
Use of uninitialized value in <HANDLE> at ./test.pl line 248. readline() on unopened filehandle at ./test.pl line 248.
Shouldn't the failure to execute httpd have been printed to that $err filehandle so that I can trap it? Or is that just for errors from the executed process itself?

I've tried all kinds of gymnastics using backtick shell commands, pipes, etc. but haven't found a way to trap the failure to execute.

Any input would be greatly appreciated!

Replies are listed 'Best First'.
Re: Error handling in Inter Process Communication
by zentara (Cardinal) on Aug 29, 2010 at 11:51 UTC
    I'm not sure about what error you are trying to catch, but you just may want
    my $pid = open3( $wtr, $rdr, $err, $httpd, '-v' ) or die " spawning bi +nary failed $!\n ";
    or even
    my $pid = open3( $wtr, $rdr, $err, $httpd, '-v' ); if ( $pid ){ print "success\n"} else {print "spawning failure $!\n"; }

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: Error handling in Inter Process Communication
by salva (Canon) on Aug 29, 2010 at 09:00 UTC
    IPC::Open3::open3 handles its third argument in an special way. If you pass undef there it will send the child STDERR stream to the same handler as STDOUT.

    Use non-lexical filehandles or preinitialize $err. From the module SYNOPSIS:

    use Symbol 'gensym'; $err = gensym; $pid = open3($wtr, $rdr, $err, 'some cmd and args', 'optarg', ...);