Skip to content

Commit d55ca28

Browse files
committed
Document intricacies of exec on Windows
1 parent e4a5cb9 commit d55ca28

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

System/Process.hs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,14 @@ module System.Process (
5454
-- $ctlc-handling
5555

5656
-- * Process completion
57+
-- ** Notes about @exec@ on Windows
58+
-- $exec-on-windows
5759
waitForProcess,
5860
getProcessExitCode,
5961
terminateProcess,
6062
interruptProcessGroupOf,
6163

62-
-- Interprocess communication
64+
-- * Interprocess communication
6365
createPipe,
6466
createPipeFd,
6567

@@ -394,6 +396,32 @@ processFailedException fun cmd args exit_code =
394396
-- For even more detail on this topic, see
395397
-- <http://www.cons.org/cracauer/sigint.html "Proper handling of SIGINT/SIGQUIT">.
396398

399+
-- $exec-on-windows
400+
--
401+
-- Note that processes which use the POSIX @exec@ system call (e.g. @gcc@)
402+
-- require special care on Windows. Specifically, the @msvcrt@ C runtime used
403+
-- frequently on Windows emulates @exec@ in a non-POSIX compliant manner, where
404+
-- the caller will be terminated (with exit code 0) and execution will continue
405+
-- in a new process. As a result, on Windows it will appear as though a child
406+
-- process which has called @exec@ has terminated despite the fact that the
407+
-- process would still be running on a POSIX-compliant platform.
408+
--
409+
-- Since many programs do use @exec@, the @process@ library exposes the
410+
-- 'use_process_jobs' flag to make it possible to reliably detect when such a
411+
-- process completes. When this flag is set a 'ProcessHandle' will not be
412+
-- deemed to be \"finished\" until all processes spawned by it have
413+
-- terminated (except those spawned by the child with the
414+
-- @CREATE_BREAKAWAY_FROM_JOB@ @CreateProcess@ flag).
415+
--
416+
-- Note, however, that, because of platform limitations, the exit code returned
417+
-- by @waitForProcess@ and @getProcessExitCode@ cannot not be relied upon when
418+
-- the child uses @exec@, even when 'use_process_jobs' is used. Specifically,
419+
-- these functions will return the exit code of the *original child* (which
420+
-- always exits with code 0, since it called @exec@), not the exit code of the
421+
-- process which carried on with execution after @exec@. This is different from
422+
-- the behavior prescribed by POSIX but is the best approximation that can be
423+
-- realised under the restrictions of the Windows process model.
424+
397425
-- -----------------------------------------------------------------------------
398426

399427
-- | @readProcess@ forks an external process, reads its standard output

System/Process/Common.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ data CreateProcess = CreateProcess{
103103
--
104104
-- @since 1.4.0.0
105105
use_process_jobs :: Bool -- ^ On Windows systems this flag indicates that we should wait for the entire process tree
106-
-- to finish before unblocking. On POSIX systems this flag is ignored.
106+
-- to finish before unblocking. On POSIX systems this flag is ignored. See $exec-on-windows for details.
107107
--
108108
-- Default: @False@
109109
--

0 commit comments

Comments
 (0)