Scary IPC::Open3 filehandle difference

Discussion in 'Perl Misc' started by Mike Hunter, Oct 28, 2004.

  1. Mike Hunter

    Mike Hunter Guest

    Hi,

    I was experimenting with Open3 and wrote the following two programs:

    ======buggy.pl:
    #!/usr/local/bin/perl -w

    use strict;

    foreach my $i (1 .. 100)
    {
    print STDERR "STDERR $i\n";
    print "STDOUT $i\n";
    }

    ======buggy.pl:
    #!/usr/local/bin/perl -w

    use strict;
    use IPC::Open3;
    use IO::Select;

    print "starting wrapper...\n";

    my $pid = open3(\*WTRFH, \*RDRFH, \*ERRFH, @ARGV);

    my $s = IO::Select->new();

    #$s->add($wtrfh);
    $s->add(\*RDRFH);
    $s->add(\*ERRFH);

    my $timeout = 1;
    my $first_timeout = 3600;
    my @ready = $s->can_read($first_timeout);

    print "scalar @ready = ".(scalar @ready)."\n";

    my $timeouts = 0;
    while (scalar @ready)
    {
    print "on timeout $timeouts\n";
    $timeouts++;
    my $i = 0;
    foreach my $fh (@ready)
    {
    my $result;

    my $j = 0;
    while ($result = <$fh>)
    {
    print "read $j: fh_$i #$fh# says: #".$result."#\n";
    $j++;
    }
    $i++;
    }
    @ready = $s->can_read($timeout);
    print "scalar @ready = ".(scalar @ready)."\n";
    }
    print "wrapper finished\n";

    Ok, so I run the following:

    ../wrapper.pl ./buggy.pl

    and I get

    starting wrapper...
    scalar GLOB(0x805cba4) GLOB(0x805cb44) = 2
    on timeout 0
    read 0: fh_0 #GLOB(0x805cba4)# says: #STDOUT 1
    #
    read 1: fh_0 #GLOB(0x805cba4)# says: #STDOUT 2
    #
    read 2: fh_0 #GLOB(0x805cba4)# says: #STDOUT 3
    #
    read 3: fh_0 #GLOB(0x805cba4)# says: #STDOUT 4
    #
    read 4: fh_0 #GLOB(0x805cba4)# says: #STDOUT 5
    #
    read 5: fh_0 #GLOB(0x805cba4)# says: #STDOUT 6
    #
    read 6: fh_0 #GLOB(0x805cba4)# says: #STDOUT 7
    #
    read 7: fh_0 #GLOB(0x805cba4)# says: #STDOUT 8
    #
    read 8: fh_0 #GLOB(0x805cba4)# says: #STDOUT 9
    #
    read 9: fh_0 #GLOB(0x805cba4)# says: #STDOUT 10
    #
    read 0: fh_1 #GLOB(0x805cb44)# says: #STDERR 1
    #
    read 1: fh_1 #GLOB(0x805cb44)# says: #STDERR 2
    #
    read 2: fh_1 #GLOB(0x805cb44)# says: #STDERR 3
    #
    read 3: fh_1 #GLOB(0x805cb44)# says: #STDERR 4
    #
    read 4: fh_1 #GLOB(0x805cb44)# says: #STDERR 5
    #
    read 5: fh_1 #GLOB(0x805cb44)# says: #STDERR 6
    #
    read 6: fh_1 #GLOB(0x805cb44)# says: #STDERR 7
    #
    read 7: fh_1 #GLOB(0x805cb44)# says: #STDERR 8
    #
    read 8: fh_1 #GLOB(0x805cb44)# says: #STDERR 9
    #
    read 9: fh_1 #GLOB(0x805cb44)# says: #STDERR 10
    #
    ....

    (still need to write the code to close-out properly)

    Anyway, my frist draft had wrapper.pl with the following slightly-different
    opening lines:

    my ($wtrfh, $rdrfh, $errfh);
    my $pid = open3($wtrfh, $rdrfh, $errfh, @ARGV);

    my $s = IO::Select->new();

    #$s->add($wtrfh);
    $s->add($rdrfh);
    $s->add($errfh);

    And I get the following nutz-oid output:

    starting wrapper...
    scalar GLOB(0x805cb2c) = 1
    on timeout 0
    read 0: fh_0 #GLOB(0x805cb2c)# says: #STDERR 1
    #
    read 1: fh_0 #GLOB(0x805cb2c)# says: #STDERR 2
    #
    read 2: fh_0 #GLOB(0x805cb2c)# says: #STDERR 3
    #
    read 3: fh_0 #GLOB(0x805cb2c)# says: #STDERR 4
    #
    read 4: fh_0 #GLOB(0x805cb2c)# says: #STDERR 5
    #
    read 5: fh_0 #GLOB(0x805cb2c)# says: #STDERR 6
    #
    read 6: fh_0 #GLOB(0x805cb2c)# says: #STDERR 7
    #
    read 7: fh_0 #GLOB(0x805cb2c)# says: #STDERR 8
    #
    read 8: fh_0 #GLOB(0x805cb2c)# says: #STDERR 9
    #
    read 9: fh_0 #GLOB(0x805cb2c)# says: #STDERR 10
    #
    read 10: fh_0 #GLOB(0x805cb2c)# says: #STDOUT 1
    #
    read 11: fh_0 #GLOB(0x805cb2c)# says: #STDOUT 2
    #
    read 12: fh_0 #GLOB(0x805cb2c)# says: #STDOUT 3
    #
    read 13: fh_0 #GLOB(0x805cb2c)# says: #STDOUT 4
    #
    read 14: fh_0 #GLOB(0x805cb2c)# says: #STDOUT 5
    #
    read 15: fh_0 #GLOB(0x805cb2c)# says: #STDOUT 6
    #
    read 16: fh_0 #GLOB(0x805cb2c)# says: #STDOUT 7
    #
    read 17: fh_0 #GLOB(0x805cb2c)# says: #STDOUT 8
    #
    read 18: fh_0 #GLOB(0x805cb2c)# says: #STDOUT 9
    #
    read 19: fh_0 #GLOB(0x805cb2c)# says: #STDOUT 10
    #

    So somehow, it does 20 reads on the same filehandle, which has magically gotten
    STDOUT and STDERR of buggy.pl....

    ???

    Oh perl gods, reveal unto me my wickedness.

    Mike

    BTW this is perl 5.8.2 on fbsd 5.3-beta5
    Mike Hunter, Oct 28, 2004
    #1
    1. Advertising

  2. On 2004-10-28, Mike Hunter <> wrote:
    > my $pid = open3(\*WTRFH, \*RDRFH, \*ERRFH, @ARGV);

    ....
    > Anyway, my frist draft had wrapper.pl with the following slightly-different
    > opening lines:
    >
    > my ($wtrfh, $rdrfh, $errfh);
    > my $pid = open3($wtrfh, $rdrfh, $errfh, @ARGV);

    ....
    > So somehow, it does 20 reads on the same filehandle, which has magically gotten
    > STDOUT and STDERR of buggy.pl....


    The documentation for IPC::Open3 says:

    If ERRFH is false, or the same file descriptor as RDRFH, then
    STDOUT and STDERR of the child are on the same filehandle.

    Note the part about ERRFH being false. Also note that undef is false.

    So yes, according to the documentation it _is_ supposed to work like
    that. That said, it does feel rather stupid. It also means the two
    code examples in the synopsis don't do the same thing, even though the
    latter certainly looks like it should do the same as the former.

    So I suppose the question is how much legacy code would break if it
    was changed to work in a more sensible way. Any guesses?

    --
    Ilmari Karonen
    To reply by e-mail, please replace ".invalid" with ".net" in address.
    Ilmari Karonen, Dec 14, 2004
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dave Newberry
    Replies:
    0
    Views:
    645
    Dave Newberry
    Oct 17, 2004
  2. J. Romano
    Replies:
    0
    Views:
    158
    J. Romano
    Feb 10, 2004
  3. Rocky Allen

    IPC::Open3

    Rocky Allen, Aug 24, 2005, in forum: Perl Misc
    Replies:
    4
    Views:
    114
    Joe Smith
    Aug 24, 2005
  4. Rocky Allen

    IPC::Open3 issue

    Rocky Allen, Aug 24, 2005, in forum: Perl Misc
    Replies:
    2
    Views:
    137
    Rocky Allen
    Aug 24, 2005
  5. Peter Makholm

    IPC::Open3 and the error filehandle

    Peter Makholm, Oct 26, 2007, in forum: Perl Misc
    Replies:
    5
    Views:
    198
    Peter Makholm
    Oct 29, 2007
Loading...

Share This Page