Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re^3: Forks, Pipes and Exec (file descriptors)

by diabelek (Beadle)
on Nov 06, 2008 at 18:01 UTC ( #722052=note: print w/replies, xml ) Need Help??


in reply to Re^2: Forks, Pipes and Exec (file descriptors)
in thread Forks, Pipes and Exec

Update...

This works great in Linux but now I'm trying to get it working in Windows. The problem is that Windows doesn't seem to have the process print to the pipe that's attached to stdout. The only thing I can gather from testing variations is that STDOUT is the same for both "processes" in Windows. If I sleep and let the child run first or don't restore STDOUT, the pipe works as designed. As soon as I restore STDOUT, the pipe is broken even though they are separate processes.

Is there any way of doing this in Windows?

print "before the pipe\n"; open $old_stdout, ">&STDOUT" or die "open: $!"; local(*WH); pipe $rh, WH; open STDOUT, ">&WH" or die "open: $!"; STDOUT->blocking(0); # write something to the pipe # and have some fork/exec'ed process write to the pipe (via stdout) if( fork() ) { open( STDOUT, ">&", $old_stdout ) or die "open: $!"; print STDERR "I'm the parent\n"; sleep 3; } else { exec( 'echo fubar' ); exit( 0 ); } close WH; my $out = <$rh>; print "got from pipe: $out"; # $out is empty since fubar printed to +the screen

Replies are listed 'Best First'.
Re^4: Forks, Pipes and Exec (file descriptors)
by BrowserUk (Pope) on Nov 06, 2008 at 19:17 UTC

      If it is a separate thread, is there any way to have STDOUT for thread A be different from thread B?

      From the activestate documentation, the STDOUT filehandle should have been duped for the child thread but I don't believe that's what I'm seeing. I can make a change in the parent to STDOUT that affects the child's STDOUT. Can anyone explain what I'm missing?

      active state documentation http://www.xav.com/perl/lib/Pod/perlfork.html
      "Open filehandles
      Any filehandles open at the time of the fork() will be dup()-ed. Thus, the files can be closed independently in the parent and child, but beware that the dup()-ed handles will still share the same seek pointer. Changing the seek position in the parent will change it in the child and vice-versa. One can avoid this by opening files that need distinct seek pointers separately in the child."

        I can make a change in the parent to STDOUT that affects the child's STDOUT.

        It depends what change you are making and how you are perceiving that the the child has been affected.

        In general, I do not consider Perl's Win32 fork emulation worth the effort of bothering with. There are simply too many differences between the platforms and holes in the emulation, that make *nix techniques fail to work. A few examples:

        • In your snippet above, you create a pipe and set it up as stdout and then you attempt to set it non-blocking, presumably with the intent of use select upon it.

          But win32 anonymous pipes cannot be set non-blocking and so cannot be used in conjunction with select.

          Note:Win32 pipes can be used in a non-blocking fashion--using peeking (polling) or asynchronous IO or overlapped IO, but none of these fit well with the select mode of operations. This is not a limitation, but rather a difference in design philosophy that is hard to reconcile in a portable fashion.

        • If you do a fork followed by exec on *nix, then the pid returned to the 'parent' is process handle to the newly started process.

          If you do the same thing using the win32 emulation, the 'pid' is actually a disguised thread handle to a thread, and the process you "exec'd" is actually started as an entirely new process (using what is effectively the same as system), with an entirely different pid to that returned by fork--and to which you can never get access.

          Consequently, anything the parent does with that pseudo-pid only affects the thread--not the "exec'd" process. Eg. killing the pseudo-pid (or attempting send almost any signal) will terminate the thread, but leave the process running.

          Again, it is perfectly possible to set up bi-directional communications between a parent and child process under win32 at the C-level, but far harder to see how to make this available to Perl programs ina platform agnostic way.

        • Signals are not implemented (by the system) on win32, and only a handful (2,3,15,21) are emulated in a way that can be trapped.

          That means you will never receive a SIGCHLD in the parent. Whilst wait and waitpid are emulated, it is done by having the child thread block in a system wait on the child process, which makes for very different and confusing semantics.

        Those are just a few of the limitations that come to mind. I've encountered several more anomalies that don't. IMO these difference make trying to code portable programs using fork unworkable if win32 is a target platform.

        If you application calls for single direction piping of data to or from the child, then using the forked-open is effective and far more portable. If you bi-directional communications between parent and child, then threads can provide an effective solution that is again, far more portable than fork.

        Your question to date simply asks about forking and pipes ,without giving any hint as to the actual application, so it is impossible to suggest alternatives to that approach.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2019-07-18 23:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?