in reply to Re: Doubled print with eval and open3
in thread Doubled print with eval and open3

The open3 doesn't throw an exception so the eval doesn't catch it.

If that's true, why is "Error, Could not executed" printed. That's part of the exception handler.

If that's true, does that mean the following passage from IPC::Open3's docs is wrong?

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.

Replies are listed 'Best First'.
Re^3: Doubled print with eval and open3
by GrandFather (Saint) on Mar 06, 2007 at 00:33 UTC

    Hmm, interesting. I ran OP's code under a debugger as a learning exercise, and thought I'd inferred the problem. Maybe I just found a different one:

    If that's true, why is "Error, Could not executed" printed.

    On Windows it's not - there's a clue right there! Actually on Windows the OP's sample code just prints a comma. The following:

    use strict; use warnings; use IPC::Open3; use IO::Select; use POSIX ":sys_wait_h"; use Symbol; my $ERROR=gensym(); my $command="not_a_command"; my ($WRITE, $READ); my $pid; $! = undef; eval {$pid = open3($WRITE, $READ, $ERROR, "$command");}; print "pid is $pid\n" if $pid; if ($@) { print "Trapped error $@"; } elsif (length $!) { print "Detected error: $!"; } else { print "No error"; }

    prints:

    pid is 3412 Detected error: No such file or directory

    on Windows.


    DWIM is Perl's answer to Gödel
      And for FreeBSD 6.1 and Perl 5.8.8, I get
      pid is 18693 No error

      The error occured in the forked child process, so the exec or die would get sent to the file handle piped to $ERROR, and only the child's $! would be affected if the fork succeeded.

      ikegami erases the paragraph he was writting.
      Oo! I just figured it out!

      The OP must be on a system where fork is used ($^O eq 'os2' || $^O eq 'MSWin32' is false). The fork succeeds, but the exec fails. He's getting output from both the child and the parent! Fix:

      my $pid = eval { open3($WRITE, $READ, $ERROR, "$command") }; if (!$pid) { # We're in the child. # The fork succeeded, but the exec failed. POSIX::_exit($!); } ...

      Update: Oops! Looks like almut beat me to it here