Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Re^4: Win32API::File not setting HANDLE_FLAG_PROTECT_FROM_CLOSE (sources)

by Yary (Monk)
on Dec 05, 2012 at 13:20 UTC ( #1007287=note: print w/ replies, xml ) Need Help??

in reply to Re^3: Win32API::File not setting HANDLE_FLAG_PROTECT_FROM_CLOSE (sources)
in thread Win32API::File not setting HANDLE_FLAG_PROTECT_FROM_CLOSE

Hi & thanks for persisting. I'm going to post the working UNIX version of the entire program chain, with its debugging statements, for reference.

#!/usr/bin/env perl use warnings; use strict; use Fcntl qw(F_GETFD F_SETFD FD_CLOEXEC); open my $fh,">&2"; unless (@ARGV && $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 $fh "This is to fd $ENV{myfd} from the parent\n";

#!/usr/bin/env perl use warnings; use strict; open OUT,">&=$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";
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 & stderr to filehandles the parent can read from, but I don't want to get bogged down in more details here.

The above is what got me wanting to set _PROTECT_FROM_CLOSE. If you run ./ noset the pair of programs fail, you have to protect FD 3 from going away when the child exec's into a new process.

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 _PROTECT_FROM_CLOSE. On the other hand, _INHERIT is already set, hence the flags was=1 debug output, so that isn't the issue.

Here's the pair of programs modified for Windows. The outer program is most of the code already posted, with even more debug info.

#!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,">&2"; $^F = 3; my $os_handle=GetOsFHandle($fh) or die "Can't GetOSFHandle: $^E,\nstop +ped"; #$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 SetHandleInfo +rmation: $^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",1,0, " +." ) # or die "Can't run: $^E\n"; system ''; print $fh "This is to fd $ENV{myfd} from the parent\n";

open OUT,">&=$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";

Comment on Re^4: Win32API::File not setting HANDLE_FLAG_PROTECT_FROM_CLOSE (sources)
Select or Download Code
Replies are listed 'Best First'.
Re^5: Win32API::File not setting HANDLE_FLAG_PROTECT_FROM_CLOSE (wrong layer)
by tye (Sage) on Dec 05, 2012 at 14:47 UTC

    The flags are on the OsFHandle and yet you are trying to share the Unixish 'fd'. Try $ENV{myosh} = $os_handle; instead and then open an fd and fh for that in the spawned process (via OsFHandleOpen).

    That's how I've done this successfully before.

    - tye        

      That works. Adding $ENV{myosh} = $os_handle; to the caller (also removing SetHandleInformation, it isn't needed) and rewriting as
      use Win32API::File qw(OsFHandleOpen); OsFHandleOpen(\*OUT,$ENV{myosh},"w"); $x=print OUT "***\nHere is data to OsH $ENV{myosh}\n***\n"; warn "print=$x ($!)\n" unless $x;
      works... Alas the "real" code I am dealing with that "" replaces is Unix-y C code. I have already made it use STDERR instead of its own stream, which is working well enough- if there's an error message then the stream is no good anyway, and in the usual case it's easier to manipulate STDERR .

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1007287]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (11)
As of 2015-11-26 08:31 GMT
Find Nodes?
    Voting Booth?

    What would be the most significant thing to happen if a rope (or wire) tied the Earth and the Moon together?

    Results (696 votes), past polls