To maintain full control over all aspects of pipes, buffering, batching (e.g. reading and writing 1000 records at a time between two external programs) and so on (my external program is usually RDBMS or TSDBMS related), I usually need to write my own classes to manage open3, instead of using Run3, e.g. something like:
use IPC::Open3; use POSIX ":sys_wait_h"; package Query; sub new { my $self = shift; my %opt = @_; $self = \%opt; defined $self -> { SERVICE } or $self -> { SERVICE } = 'defaultqueryprog'; if ( defined $self -> { SEND } ) { my $pid = open3 my $wh, my $rh, my $eh, $self -> { SERVICE } or warn "$!: " . $self -> { SERVICE } . "\n" && exit $?; $self -> { WH } = $wh; $self -> { RH } = $rh; $self -> { EH } = $eh; $self -> { PID } = $pid; write $wh $self -> { SEND } . "\n"; } else { my $pid = open3 undef(), my $rh, my $eh, $self -> { SERVICE } or warn "$!: " . $self -> { SERVICE } . "\n" && exit $?; $self -> { RH } = $rh; $self -> { EH } = $eh; $self -> { PID } = $pid; } return bless $self; # note the pipe is not closed! } sub fetch { my $self = shift; my $rh = $self -> { RH }; my $eh = $self -> { EH }; my $oneliner = !wantarray; unless ( $oneliner &&= <$rh> ) { # cleanup if and only if flushing the pipe my @out = <$rh>; close $rh; my @err = <$eh>; close $eh; $self -> { STDERR } = \@err; waitpid $self -> { PID },0; delete $self -> { PID }; return @out; } return $oneliner; } sub fetcherror { # similar to fetch but on $self -> { EH }; ... } sub shut { my $self = shift; close $self -> { RH }, $self -> { EH }; $sts = $?; waitpid $self -> { PID }, 0; delete $self -> { PID }; return $sts; } 1;
-M
Free your mind
In reply to Re: Script hangs when called via IPC::Open3
by Moron
in thread Script hangs when called via IPC::Open3
by jeffa
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |