Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Scary IPC::Open3 filehandle difference

Reply
Thread Tools

Scary IPC::Open3 filehandle difference

 
 
Mike Hunter
Guest
Posts: n/a
 
      10-28-2004
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
 
Reply With Quote
 
 
 
 
Ilmari Karonen
Guest
Posts: n/a
 
      12-14-2004
On 2004-10-28, Mike Hunter <(E-Mail Removed)> 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.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Scary website design Weyoun the Dancing Borg HTML 13 05-28-2004 03:23 PM
scary flybynight IT contractors Hugo Drax Cisco 3 12-12-2003 09:50 PM
Ok Scary Josh Computer Support 8 11-05-2003 03:34 AM
Scary ! slumpy Computer Support 8 08-07-2003 12:24 PM
Now here's a very scary thought nowhere man Computer Support 2 07-16-2003 12:43 AM



Advertisments