Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
IPC::Run::Win32Helper(User Contributed Perl DocumentatIPC::Run::Win32Helper(3)

       IPC::Run::Win32Helper - helper routines for IPC::Run on Win32

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

       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, thanks!.

	   Most	common incantations of "run()" (not "harness()", "start()", or
	   "finish()") now use temporary files to redirect input and output
	   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
	   unfiltered 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,
	   filehandles 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
	   communicating 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
	   optimizations; 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

       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
	   benefits 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"
	   processes are used to overcome the inconsistencies 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
	   CreateProcess(), child processes with redirects are quite slow to
	   launch; so this routine looks for the very common case of
	   reading/writing to/from scalar references in	a run()	routine	and
	   converts such reads and writes in to	temporary file reads and

	   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

	   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 highlight those calls that aren't

	      @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 so	all spawned processes get the benefit.

	   LIMITATIONS:	shellwords dies	silently on malformed input like


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


	   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 "OsFHandleOpen()" 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.

       Barries Slaymaker <>.	 Funded	by Perforce Software,

       Copyright 2001, Barrie Slaymaker, All Rights Reserved.

       You may use this	under the terms	of either the GPL 2.0 or the Artistic

perl v5.32.1			  2020-05-05	      IPC::Run::Win32Helper(3)


Want to link to this manual page? Use this URL:

home | help