The cause is indeed that the subroutine is returning and closing the pipe to the external program without waiting for the child to finish. The number 1030 it reaches is probably just a buffering threshold at which it is waiting for the parent to flush - having not released the buffer it is not even looking for a closed pipe from the other side.

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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.