IPC::Run::Win32Helper

TriggerTek Logo
abcdefghijklmnopqrstuvwxyz_
IPC::Run::Win32HelperUser Contributed Perl DocumentatIPC::Run::Win32Helper(3)



NAME
       IPC::Run::Win32Helper - helper routines for IPC::Run on Win32 plat-
       forms.

SYNOPSIS
	   use IPC::Run::Win32Helper;	# Exports all by default

DESCRIPTION
       IPC::Run needs to use sockets to redirect subprocess I/O so that the
       select() loop will work on Win32. This seems to only work on WinNT and
       Win2K at this time, not sure if it will ever work on Win95 or Win98.
       If you have experience in this area, please contact me at bar-
       ries@slaysys.com, thanks!.

FUNCTIONS
       optimize()
	   Most common incantations of "run()" (not "harness()", "start()",
	   or "finish()") now use temporary files to redirect input and out-
	   put instead of pumper processes.

	   Temporary files are used when sending to child processes if input
	   is taken from a scalar with no filter subroutines.  This is the
	   only time we can assume that the parent is not interacting with
	   the child’s redirected input as it runs.

	   Temporary files are used when receiving from children when output
	   is to a scalar or subroutine with or without filters, but only if
	   the child in question closes its inputs or takes input from unfil-
	   tered SCALARs or named files.  Normally, a child inherits its
	   STDIN from its parent; to close it, use "0<&-" or the "noinherit
	   =" 1> option.  If data is sent to the child from CODE refs, file-
	   handles or from scalars through filters than the child’s outputs
	   will not be optimized because "optimize()" assumes the parent is
	   interacting with the child.	It is ok if the output is filtered or
	   handled by a subroutine, however.

	   This assumes that all named files are real files (as opposed to
	   named pipes) and won’t change; and that a process is not communi-
	   cating with the child indirectly (through means not visible to
	   IPC::Run).  These can be an invalid assumptions, but are the 99%
	   case.  Write me if you need an option to enable or disable opti-
	   mizations; I suspect it will work like the "binary()" modifier.

	   To detect cases that you might want to optimize by closing inputs,
	   try setting the "IPCRUNDEBUG" environment variable to the special
	   "notopt" value:

	      C:> set IPCRUNDEBUG=notopt
	      C:> my_app_that_uses_IPC_Run.pl

       optimizer() rationalizations
	   Only for that limited case can we be sure that it’s ok to batch
	   all the input in to a temporary file.  If STDIN is from a SCALAR
	   or from a named file or filehandle (again, only in "run()"), then
	   outputs to CODE refs are also assumed to be safe enough to batch
	   through a temp file, otherwise only outputs to SCALAR refs are
	   batched.  This can cause a bit of grief if the parent process ben-
	   efits from or relies on a bit of "early returns" coming in before
	   the child program exits.  As long as the output is redirected to a
	   SCALAR ref, this will not be visible.  When output is redirected
	   to a subroutine or (deprecated) filters, the subroutine will not
	   get any data until after the child process exits, and it is likely
	   to get bigger chunks of data at once.

	   The reason for the optimization is that, without it, "pumper" pro-
	   cesses are used to overcome the inconsistancies of the Win32 API.
	   We need to use anonymous pipes to connect to the child processes’
	   stdin, stdout, and stderr, yet select() does not work on these.
	   select() only works on sockets on Win32.  So for each redirected
	   child handle, there is normally a "pumper" process that connects
	   to the parent using a socket--so the parent can select() on that
	   fd--and to the child on an anonymous pipe--so the child can
	   read/write a pipe.

	   Using a socket to connect directly to the child (as at least one
	   MSDN article suggests) seems to cause the trailing output from
	   most children to be lost.  I think this is because child processes
	   rarely close their stdout and stderr explicitly, and the winsock
	   dll does not seem to flush output when a process that uses it
	   exits without explicitly closing them.

	   Because of these pumpers and the inherent slowness of Win32 Cre-
	   ateProcess(), child processes with redirects are quite slow to
	   launch; so this routine looks for the very common case of read-
	   ing/writing to/from scalar references in a run() routine and con-
	   verts such reads and writes in to temporary file reads and writes.

	   Such files are marked as FILE_ATTRIBUTE_TEMPORARY to increase
	   speed and as FILE_FLAG_DELETE_ON_CLOSE so it will be cleaned up
	   when the child process exits (for input files).  The user’s
	   default permissions are used for both the temporary files and the
	   directory that contains them, hope your Win32 permissions are
	   secure enough for you.  Files are created with the Win32API::File
	   defaults of FILE_SHARE_READ│FILE_SHARE_WRITE.

	   Setting the debug level to "details" or "gory" will give detailed
	   information about the optimization process; setting it to "basic"
	   or higher will tell whether or not a given call is optimized.
	   Setting it to "notopt" will highligh those calls that aren’t opti-
	   mized.

       win32_parse_cmd_line
	      @words = win32_parse_cmd_line( q{foo bar ’baz baz’ "bat bat"} ) ;

	   returns 4 words. This parses like the bourne shell (see the bit
	   about shellwords() in Text::ParseWords), assuming we’re trying to
	   be a little cross-platform here.  The only difference is that "\"
	   is *not* treated as an escape except when it precedes punctuation,
	   since it’s used all over the place in DOS path specs.

	   TODO: globbing? probably not (it’s unDOSish).

	   TODO: shebang emulation? Probably, but perhaps that should be part
	   of Run.pm so all spawned processes get the benefit.

	   LIMITATIONS: shellwords dies silently on malformed input like

	      a\"

       win32_spawn
	   Spawns a child process, possibly with STDIN, STDOUT, and STDERR
	   (file descriptors 0, 1, and 2, respectively) redirected.

	   LIMITATIONS.

	   Cannot redirect higher file descriptors due to lack of support for
	   this in the Win32 environment.

	   This can be worked around by marking a handle as inheritable in
	   the parent (or leaving it marked; this is the default in perl),
	   obtaining it’s Win32 handle with "Win32API::GetOSFHandle(FH)" or
	   "Win32API::FdGetOsFHandle($fd)" and passing it to the child using
	   the command line, the environment, or any other IPC mechanism
	   (it’s a plain old integer).	The child can then use "OsFHan-
	   dleOpen()" or "OsFHandleOpenFd()" and possibly "<open FOO
	   ""&BAR">> or "<open FOO ""&$fd>> as need be.	 Ach, the pain!

	   Remember to check the Win32 handle against INVALID_HANDLE_VALUE.

AUTHOR
       Barries Slaymaker <barries@slaysys.com>.	 Funded by Perforce Software,
       Inc.

COPYRIGHT
       Copyright 2001, Barrie Slaymaker, All Rights Reserved.

       You may use this under the terms of either the GPL 2.0 ir the Artistic
       License.



perl v5.8.8			  2006-05-10	     IPC::Run::Win32Helper(3)