M
Mike Hunter
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
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