perl-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Steve Hay <steve....@uk.radan.com>
Subject Re: t/SMOKE on win32
Date Mon, 06 Oct 2003 14:59:39 GMT
Randy Kobes wrote:

>I've tried now a couple of things, but without success:
>- redirecting STDOUT/STDERR to a temporary file within
>the parent, and then calling run3 as
>    run3 $command, undef, undef, undef;
>which is supposed to inherit the parent's STDs. This
>worked fine on linux, but not on Win32.
>
I've got very confused over exactly what does work and what doesn't 
(just in simple Perl terms, leaving mod_perl out of it for now), so I 
wrote a few test scripts to clear things up.

I've attached an archive of them.  Each of the scripts test1.pl through 
test6.pl try to run another Perl script called command.pl which writes 
"Hello" to STDOUT and "Hi! from command.pl" to STDERR.  The test scripts 
seek to capture STDOUT by a variety of means, leaving STDERR untouched 
just to see that the command.pl did actually run, and then print what 
they've captured.

Here's what each test script does:

test1.pl passes a scalar to run3
test2.pl redirects STDOUT to a scalar and has run3 inherit it
test3.pl redirects STDOUT to a scalar and passes that scalar to run3
test4.pl passes a file to run3
test5.pl redirects STDOUT to a file and has run3 inherit it
test6.pl redirects STDOUT to a file and passes that file to run3

and here's the results with IPCRUN3DEBUG set to 5:

=====
C:\Temp>test1.pl
run3(): running 'C:\perl5\bin\perl.exe C:\Temp\command.pl'
run3(): capturing child stdout
Hi! from command.pl
run3(): $? is 0
run3(): reading child stdout to SCALAR
run3(): read 5 bytes from child stdout: 'Hello'
Captured 'Hello' from STDOUT
Done

C:\Temp>test2.pl
run3(): running 'C:\perl5\bin\perl.exe C:\Temp\command.pl'
Hi! from command.pl
run3(): $? is 0
Captured '' from STDOUT
Done

C:\Temp>test3.pl
run3(): running 'C:\perl5\bin\perl.exe C:\Temp\command.pl'
run3(): capturing child stdout
Hi! from command.pl
run3(): $? is 0
run3(): reading child stdout to SCALAR
Captured '' from STDOUT
Done

C:\Temp>test4.pl
run3(): running 'C:\perl5\bin\perl.exe C:\Temp\command.pl'
run3(): feeding child stdout to file 'C:\Temp\output.txt'
Hi! from command.pl
run3(): $? is 0
Captured 'Hello' from STDOUT
Done

C:\Temp>test5.pl
run3(): running 'C:\perl5\bin\perl.exe C:\Temp\command.pl'
Hi! from command.pl
run3(): $? is 0
Captured 'Hello' from STDOUT
Done

C:\Temp>test6.pl
run3(): running 'C:\perl5\bin\perl.exe C:\Temp\command.pl'
run3(): feeding child stdout to file 'C:\Temp\output.txt'
Hi! from command.pl
run3(): $? is 0
Captured 'Hello' from STDOUT
Done
=====

So it seems that run3 works fine when passed a scalar or a file, i.e. as 
it is intended to be used (test1 & test4).  But when we muck around 
doing redirections ourselves first and expect run3 to inherit those 
redirections, it only works for files (test5 & test6), not for scalars 
(test2 & test3)!

In short, we should be safe using IPC::Run3 as it was intended to be 
used.  The fact that test2 & test3 didn't work is maybe a bug in 
IPC::Run3, but, as Barrie has pointed out in another mail, there's not 
much point in using IPC::Run3 at all if you're mucking about with 
redirections yourself - IPC::Run3 was meant to save you all that bother.

However, I've now tried mod_perl's SMOKE with TestSmoke.pm coded like 
test1 and test4 in turn, and neither one worked.

So what's the difference?  Is it that with mod_perl's SMOKE the command 
being run via run3 actually does some redirections itself?  If I replace 
the command.pl used in the tests above with a version that redirects 
STDOUT before printing "Hello" to it and then restores it again 
afterwards, I find that test1 & test4 (the two "purest" tests which 
worked before) now fail to capture anything, i.e. with this:

command.pl:
===========
use strict;
use warnings;

my $savout;
open $savout, '>&STDOUT' or die "Can't dup STDOUT: $!\n";
close STDOUT or die "Can't close original STDOUT: $!\n";
my $logout = '';
open STDOUT, '>', \$logout or die "Can't redirect STDOUT: $!\n";

print STDOUT 'Hello';
print STDERR "Hi! from command.pl\n";

close STDOUT or die "Can't close redirected STDOUT: $!\n";
open STDOUT, '>&', $savout or die "Can't restore STDOUT: $!\n";
close $savout or die "Can't close saved STDOUT: $!\n";
===========

we now get:

=====
C:\Temp>test1.pl
run3(): running 'C:\perl5\bin\perl.exe C:\Temp\command.pl'
run3(): capturing child stdout
Hi! from command.pl
run3(): $? is 0
run3(): reading child stdout to SCALAR
Captured '' from STDOUT
Done

C:\Temp>test4.pl
run3(): running 'C:\perl5\bin\perl.exe C:\Temp\command.pl'
run3(): feeding child stdout to file 'C:\Temp\output.txt'
Hi! from command.pl
run3(): $? is 0
Captured '' from STDOUT
Done
=====

I don't know if that should have worked or not.  Does it help explain 
what is going on?  I'm still confused, though, because the above didn't 
generated "Can't dup STDOUT" errors like SMOKE does.

- Steve

Mime
View raw message