in reply to
Re: ActiveState woes : Is it EOF-blind?
in thread ActiveState woes : Is it EOF-blind?
You might logically expect this would trigger the sending of EOF, and presumably it does on most OS but not on Win32.
Actually, it does on Win32 as well. It is just that Perl on Win32 now has a bug such that $^F doesn't work as it is supposed to. You can use Win32API::File::SetHandleInformation() to work around this bug. The following code does what IPC::Open3 should be doing under the covers, but with two added lines of code to work around this Perl bug:
#!/usr/bin/perl -w
use strict;
use Win32API::File qw(
GetOsFHandle
GetHandleInformation
SetHandleInformation HANDLE_FLAG_INHERIT
CloseHandle
);
if( @ARGV ) {
# This is cat.pl
warn "Started child...\n";
for( @ARGV ) {
if( /\D/ ) {
} elsif( CloseHandle($_) ) {
warn "Closed $_!\n";
} else {
warn "Couldn't close $_: $^E\n";
}
}
while(<STDIN>) {
warn "Child read line...\n";
print;
warn "Child printed line...\n";
}
warn "Child done...\n";
close STDOUT
or die "Can't close STDOUT: $!\n";
close STDIN
or die "Can't close STDIN: $!\n";
exit( 0 );
}
pipe *KIDIN, *TOKID
or die "Can't create first pipe: $!\n";
pipe *FROMKID, *KIDOUT
or die "Can't create second pipe: $!\n";
open( STDIN, "<&", \*KIDIN )
or die "Can't dup2 KIDIN to STDIN: $!\n";
open( STDOUT, ">&", \*KIDOUT )
or die "Can't dup2 KIDOUT to STDOUT: $!\n";
close KIDIN
or die "Can't close KIDIN: $!\n";
close KIDOUT
or die "Can't close KIDOUT: $!\n";
# Here is the missing part:
SetHandleInformation( GetOsFHandle(\*TOKID), HANDLE_FLAG_INHERIT(), 0
+)
or die "Can't disable inherit for TOKID: $^E\n";
SetHandleInformation( GetOsFHandle(\*FROMKID), HANDLE_FLAG_INHERIT(),
+0 )
or die "Can't disable inherit for FROMKID: $^E\n";
system( 1, $^X, $0, 'cat' ) # GetOsFHandle(\*TOKID), GetOsFHandle(\*FR
+OMKID) )
or die "Can't exec self: $!\n";
# sleep 1;
close STDIN
or die "Can't close STDIN: $!\n";
close STDOUT
or die "Can't close STDOUT: $!\n";
print TOKID "first line\nsecond line\n";
close TOKID
or die "Can't close TOKID: $!\n";
warn "closed TOKID\n";
my @result= <FROMKID>;
print STDERR "RESULT:\n", @result, "\n";
close FROMKID
or die "Can't close FROMKID: $!\n";
Using SetHandleInformation() to turn off the HANDLE_FLAG_INHERIT() bit causes those two file handles to not be inherited by the child (which is like closing the handles after fork but before exec).