<?xml version="1.0" encoding="windows-1252"?>
<node id="1007287" title="Re^4: Win32API::File not setting HANDLE_FLAG_PROTECT_FROM_CLOSE (sources)" created="2012-12-05 08:20:10" updated="2012-12-05 08:20:10">
<type id="11">
note</type>
<author id="694176">
Yary</author>
<data>
<field name="doctext">
Hi &amp; thanks for persisting. I'm going to post the working UNIX version of the entire program chain, with its debugging statements, for reference.&lt;br&gt;
&lt;i&gt;call_with_3.pl&lt;/i&gt;
&lt;code&gt;
#!/usr/bin/env perl
use warnings;
use strict;
use Fcntl qw(F_GETFD F_SETFD FD_CLOEXEC);

open my $fh,"&gt;&amp;2";
unless (@ARGV &amp;&amp; $ARGV[0] eq 'noset') {
  fcntl($fh, F_SETFD, ~FD_CLOEXEC) or die "Can't set flags: $!\n";
  print "Set no close on exec\n";
}

$ENV{myfd}=fileno($fh);
system 'print_to_3.pl';

print $fh "This is to fd $ENV{myfd} from the parent\n";
&lt;/code&gt;
&lt;p&gt;&lt;i&gt;print_to_3.pl&lt;/i&gt;
&lt;code&gt;
#!/usr/bin/env perl
use warnings;
use strict;

open OUT,"&gt;&amp;=$ENV{myfd}" or die "cannot dup $ENV{myfd}: $!\n";
print "Child opened FD $ENV{myfd}\n";
my $p=print OUT "***\nHere is data going to fd $ENV{myfd}\n***\n";
warn "return value of print=$p ($!)\n";
&lt;/code&gt;
I'm copying the child's 3rd FD to STDERR- in real life I will want to move the child's 3rd FH to STDIN, and the child's stdin &amp; stderr to filehandles the parent can read from, but I don't want to get bogged down in more details here.
&lt;p&gt;
The above is what got me wanting to set &lt;tt&gt;_PROTECT_FROM_CLOSE&lt;/tt&gt;. If you run &lt;tt&gt;./call_with_3.pl noset&lt;/tt&gt; the pair of programs fail, you have to protect FD 3 from going away when the child exec's into a new process.
&lt;p&gt;
Windows doesn't really fork, it emulates it with a thread running a copy of the interpreter, so I can believe it won't need &lt;tt&gt;_PROTECT_FROM_CLOSE&lt;/tt&gt;. On the other hand, &lt;tt&gt;_INHERIT&lt;/tt&gt; is already set, hence the &lt;tt&gt;flags was=1&lt;/tt&gt; debug output, so that isn't the issue.
&lt;p&gt;
Here's the pair of programs modified for Windows. The outer program is most of the code already posted, with even more debug info.
&lt;br&gt;
&lt;i&gt;call_with_3.pl&lt;/i&gt;
&lt;code&gt;
#!perl -w
use strict;
use Fcntl qw(F_GETFD F_SETFD FD_CLOEXEC O_TEXT);
use Win32API::File qw(:Func :HANDLE_FLAG_);
use Win32::Process;

open my $fh,"&gt;&amp;2";
 $^F = 3;

my $os_handle=GetOsFHandle($fh) or die "Can't GetOSFHandle: $^E,\nstopped";
#$ENV{myfd}=my $ivFD = OsFHandleOpenFd($os_handle,O_TEXT);
GetHandleInformation($os_handle, my $flags);
print "HANDLE_FLAG_INHERIT=",HANDLE_FLAG_INHERIT,"\n";
print "HANDLE_FLAG_PROTECT_FROM_CLOSE=",HANDLE_FLAG_PROTECT_FROM_CLOSE,"\n";
print "flags was=$flags\n";
$flags |= HANDLE_FLAG_INHERIT|HANDLE_FLAG_PROTECT_FROM_CLOSE;
print "Trying for flags=$flags\n";
SetHandleInformation($os_handle, 0x2, 0x2) or die "Can't SetHandleInformation: $^E,\nstopped";

GetHandleInformation($os_handle, my $newflags);
print "flags now=$newflags\n";
$ENV{myfd}=fileno($fh);

my $proc;
#Win32::Process::Create($proc, $ENV{COMSPEC},"/c print_to_3.pl",1,0, "." )
#    or  die "Can't run: $^E\n";

system 'print_to_3.pl';

print $fh "This is to fd $ENV{myfd} from the parent\n";
&lt;/code&gt;
&lt;p&gt;&lt;i&gt;print_to_3.pl&lt;/i&gt;
&lt;code&gt;
open OUT,"&gt;&amp;=$ENV{myfd}" or die "cannot dup $ENV{myfd}: $!\n";
print "Opened FD $ENV{myfd}\n";
$x=print OUT "***\nHere is data to FD $ENV{myfd}\n***\n";
warn "print=$x ($!)\n";
&lt;/code&gt;
</field>
<field name="root_node">
1006121</field>
<field name="parent_node">
1006551</field>
</data>
</node>
