perlipcopen3

Warning within IPC::Open3 when using open3 twice


I am using IPC::Open3 for the suggestion given by Hans Lub here.

My issue is that the open3 call works correctly for the first time, but subsequent invocations return the warning:

Use of uninitialized value in numeric ne (!=) at /usr/lib/perl5/5.8.8/IPC/Open3.pm line 215.

The code sample I am using looks like this:

use  IPC::Open3;

my $pid;
# dup the old standard output and error 
open(OLDOUT, ">&STDOUT") or die "Can't dup STDOUT: $!\n";
open(OLDERR, ">&STDERR") or die "Can't dup STDERR: $!\n";

my $transcript_file = "transcript.temp";
# reopen stdout and stderr
open (STDOUT, "|tee -i $transcript_file") or die "Can't reopen STDOUT: $!\n";
open (STDERR, ">&STDOUT")              or die "Can't reopen STDERR: $!\n";

# print statements now write to log
print "Logging important info: blah!\n";
print STDERR "OOPS!\n";

#eval { $pid = open3("\*STDIN", "\*OLDOUT", "\*OLDERR", "ls"); }; # Tried this, but doesnt seem to help. Output does not appear on STDOUT.
eval { $pid = open3(">&STDIN", ">&OLDOUT", ">&OLDERR", "ls"); }; #This works correctly
waitpid( $pid, 0 );

eval { $pid = open3(">&STDIN", ">&OLDOUT", ">&OLDERR", "ls"); }; #First warning
waitpid( $pid, 0 );

eval { $pid = open3(">&STDIN", ">&OLDOUT", ">&OLDERR", "ls"); }; #Second warning
waitpid( $pid, 0 );

I apologize if I look to be trying to get others solve my problems, but I just can't seem to get around this, and looking inside Perl modules is beyond my current understanding.


Solution

  • It doesn't make sense to give the same STDIN to multiple parallel process. open3 thus assumes the handle you tell open3 to use isn't used by anything else, so it closes it.

    It looks like your children aren't using the STDIN you provide them, so you should provide a handle to /dev/null.

    open(local *CHILD_STDIN, '<', '/dev/null') or die $!;
    $pid = open3('<&CHILD_STDIN', '>&STDOUT', '>&STDERR', @cmd);