http://qs321.pair.com?node_id=1168753


in reply to Re^3: Perl Pipeline exception handling
in thread Perl Pipeline exception handling

Inheritance of file handles in child processes is very similar between Unix and Windows. All of the same concepts are there in both places, but they have different names and are manipulated using different functions. Perl layers the Unix-style concepts over the top of the Windows equivalents. If you want to have a Perl child process on Windows inherit a file handle, it requires you to use the Windows concepts and then rewrap them in the Unix equivalents so Perl can use them (because Perl only does that for you automatically for STDIN, STDOUT, and STDERR). Win32API::File (bundled with Perl) provides all of the tools you need to do this.

In Unix, to share a file handle with a child process that is not running the same script, that is, when you did fork(2) followed by exec (perhaps indirectly, such as via system), you have to:

  1. mark the file descriptor as "do not close on exec" (there are 2 ways to do that)
  2. fork the child and exec the new program in the child
  3. inform the child of the file descriptor (a small integer)
  4. have the child re-open the file descriptor (by passing something like "<&=$fd" to open)

In Windows, the steps are almost the same. Instead of a file descriptor, you deal with a native Windows "file handle" (a pointer, which is just a large integer), which you must not confuse with a Perl "file handle". The Windows steps are:

  1. mark the native handle so it will be inherited [using HANDLE_FLAG_INHERIT]
  2. spawn the child (don't use Perl's fork as that doesn't spawn a child, it creates a thread and a new interpreter instance)
  3. inform the child of the native handle, a large integer [requires GetOsFHandle()]
  4. have the child re-open a Perl file handle that just wraps the given native handle [using OsFHandleOpen()]

I've done this successfully without much trouble before. I thought I'd posted code for such here but my search did not turn such up. I might rewrite that later and post it.

See also: Re^2: Passing a File Descriptor to a New Process on Windows (Win32API::File)

- tye