diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,6 +1,12 @@
 module Main (main) where
 
+-- Cabal
 import Distribution.Simple
+  ( defaultMainWithHooks
+  , autoconfUserHooks
+  )
+
+--------------------------------------------------------------------------------
 
 main :: IO ()
 main = defaultMainWithHooks autoconfUserHooks
diff --git a/System/Process.hs b/System/Process.hs
new file mode 100644
--- /dev/null
+++ b/System/Process.hs
@@ -0,0 +1,1164 @@
+{-# LANGUAGE CPP, ForeignFunctionInterface #-}
+{-# LANGUAGE LambdaCase #-}
+#if __GLASGOW_HASKELL__ >= 709
+{-# LANGUAGE Safe #-}
+#else
+{-# LANGUAGE Trustworthy #-}
+#endif
+{-# LANGUAGE InterruptibleFFI #-}
+
+#include <ghcplatform.h>
+
+#if defined(javascript_HOST_ARCH)
+{-# LANGUAGE JavaScriptFFI #-}
+#endif
+
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  System.Process
+-- Copyright   :  (c) The University of Glasgow 2004-2008
+-- License     :  BSD-style (see the file libraries/base/LICENSE)
+--
+-- Maintainer  :  libraries@haskell.org
+-- Stability   :  experimental
+-- Portability :  non-portable (requires concurrency)
+--
+-- Operations for creating and interacting with sub-processes.
+--
+-----------------------------------------------------------------------------
+
+-- TODO:
+--      * Flag to control whether exiting the parent also kills the child.
+
+module System.Process (
+    -- * Running sub-processes
+
+    -- ** General interface to process creation
+
+    -- | @createProcess@ and @createProcess_@ are general interfaces
+    -- to process creation. To start with you might instead want to use
+    -- one of the [simpler process creation functions](#g:simpler)
+    -- below.
+
+    createProcess,
+    createProcess_,
+
+    -- ** Creating a @CreateProcess@
+
+    -- | Once you have a @CreateProcess@ you can launch it with
+    -- 'createProcess' or one of the [simpler process creation
+    -- functions](#g:simpler).
+
+    shell, proc,
+
+    -- ** @CreateProcess@ and associated types
+
+    CreateProcess(..),
+    CmdSpec(..),
+    StdStream(..),
+    ProcessHandle,
+
+    -- * Simpler functions for common tasks #simpler#
+
+    -- ** Call, the simplest way of launching a process
+
+    callCreateProcess,
+    callProcess,
+    callCommand,
+
+    -- ** Spawn, obtaining a @ProcessHandle@
+
+    spawnProcess,
+    spawnCommand,
+
+    -- ** Read, passing @stdin@ and obtaining @stdout@
+
+    readCreateProcess,
+    readProcess,
+
+    -- ** Read with exit code, passing @stdin@, obtaining exit code, @stdout@ and @stderr@
+
+    readCreateProcessWithExitCode,
+    readProcessWithExitCode,
+
+    -- ** Other
+
+    withCreateProcess,
+    cleanupProcess,
+
+    -- ** Related utilities
+    showCommandForUser,
+    Pid,
+    getPid,
+    getCurrentPid,
+
+    -- ** Secure process creation on Windows
+    -- $windows-mitigations
+
+    -- ** Control-C handling on Unix
+    -- $ctlc-handling
+
+    -- * Process completion
+    -- ** Notes about @exec@ on Windows
+    -- $exec-on-windows
+    waitForProcess,
+    getProcessExitCode,
+    terminateProcess,
+    interruptProcessGroupOf,
+
+    -- * Interprocess communication
+    createPipe,
+    createPipeFd,
+
+    -- * Old deprecated functions
+    -- | These functions pre-date 'createProcess' which is much more
+    -- flexible.
+    runProcess,
+    runCommand,
+    runInteractiveProcess,
+    runInteractiveCommand,
+    system,
+    rawSystem,
+    ) where
+
+import Prelude hiding (mapM)
+
+import System.Process.Internals
+
+import Control.Concurrent
+import Control.DeepSeq (rnf)
+import Control.Exception (
+#if !defined(javascript_HOST_ARCH)
+                           allowInterrupt,
+#endif
+                           bracket)
+import qualified Control.Exception as C
+import Control.Monad
+import Data.Maybe
+import Foreign
+import Foreign.C
+import System.Exit      ( ExitCode(..) )
+import System.IO
+import System.IO.Error (mkIOError, ioeSetErrorString)
+
+#if defined(javascript_HOST_ARCH)
+import System.Process.JavaScript(getProcessId, getCurrentProcessId)
+#elif defined(mingw32_HOST_OS)
+import System.Win32.Process (getProcessId, getCurrentProcessId, ProcessId)
+#else
+import System.Posix.Process (getProcessID)
+import System.Posix.Types (CPid (..))
+#endif
+
+import GHC.IO.Exception ( ioException, IOErrorType(..) )
+
+#if defined(wasm32_HOST_ARCH)
+import GHC.IO.Exception ( unsupportedOperation )
+import System.IO.Error
+#endif
+
+-- | The platform specific type for a process identifier.
+--
+-- This is always an integral type. Width and signedness are platform specific.
+--
+-- @since 1.6.3.0
+#if defined(javascript_HOST_ARCH)
+type Pid = Int
+#elif defined(mingw32_HOST_OS)
+type Pid = ProcessId
+#else
+type Pid = CPid
+#endif
+
+-- ----------------------------------------------------------------------------
+-- createProcess
+
+-- | Construct a 'CreateProcess' record for passing to 'createProcess',
+-- representing a raw command with arguments.
+--
+-- See 'RawCommand' for precise semantics of the specified @FilePath@.
+proc :: FilePath -> [String] -> CreateProcess
+proc cmd args = CreateProcess { cmdspec = RawCommand cmd args,
+                                cwd = Nothing,
+                                env = Nothing,
+                                std_in = Inherit,
+                                std_out = Inherit,
+                                std_err = Inherit,
+                                close_fds = False,
+                                create_group = False,
+                                delegate_ctlc = False,
+                                detach_console = False,
+                                create_new_console = False,
+                                new_session = False,
+                                child_group = Nothing,
+                                child_user = Nothing,
+                                use_process_jobs = False }
+
+-- | Construct a 'CreateProcess' record for passing to 'createProcess',
+-- representing a command to be passed to the shell.
+shell :: String -> CreateProcess
+shell str = CreateProcess { cmdspec = ShellCommand str,
+                            cwd = Nothing,
+                            env = Nothing,
+                            std_in = Inherit,
+                            std_out = Inherit,
+                            std_err = Inherit,
+                            close_fds = False,
+                            create_group = False,
+                            delegate_ctlc = False,
+                            detach_console = False,
+                            create_new_console = False,
+                            new_session = False,
+                            child_group = Nothing,
+                            child_user = Nothing,
+                            use_process_jobs = False }
+
+{- |
+This is the most general way to spawn an external process.  The
+process can be a command line to be executed by a shell or a raw command
+with a list of arguments.  The stdin, stdout, and stderr streams of
+the new process may individually be attached to new pipes, to existing
+'Handle's, or just inherited from the parent (the default.)
+
+The details of how to create the process are passed in the
+'CreateProcess' record.  To make it easier to construct a
+'CreateProcess', the functions 'proc' and 'shell' are supplied that
+fill in the fields with default values which can be overriden as
+needed.
+
+'createProcess' returns @(/mb_stdin_hdl/, /mb_stdout_hdl/, /mb_stderr_hdl/, /ph/)@,
+where
+
+ * if @'std_in' == 'CreatePipe'@, then @/mb_stdin_hdl/@ will be @Just /h/@,
+   where @/h/@ is the write end of the pipe connected to the child
+   process's @stdin@.
+
+ * otherwise, @/mb_stdin_hdl/ == Nothing@
+
+Similarly for @/mb_stdout_hdl/@ and @/mb_stderr_hdl/@.
+
+For example, to execute a simple @ls@ command:
+
+>   r <- createProcess (proc "ls" [])
+
+To create a pipe from which to read the output of @ls@:
+
+>   (_, Just hout, _, _) <-
+>       createProcess (proc "ls" []){ std_out = CreatePipe }
+
+To also set the directory in which to run @ls@:
+
+>   (_, Just hout, _, _) <-
+>       createProcess (proc "ls" []){ cwd = Just "/home/bob",
+>                                     std_out = CreatePipe }
+
+Note that @Handle@s provided for @std_in@, @std_out@, or @std_err@ via the
+@UseHandle@ constructor will be closed by calling this function. This is not
+always the desired behavior. In cases where you would like to leave the
+@Handle@ open after spawning the child process, please use 'createProcess_'
+instead. All created @Handle@s are initially in text mode; if you need them
+to be in binary mode then use 'hSetBinaryMode'.
+
+@/ph/@ contains a handle to the running process.  On Windows
+'use_process_jobs' can be set in CreateProcess in order to create a
+Win32 Job object to monitor a process tree's progress.  If it is set
+then that job is also returned inside @/ph/@.  @/ph/@ can be used to
+kill all running sub-processes.  This feature has been available since
+1.5.0.0.
+
+-}
+createProcess
+  :: CreateProcess
+  -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
+createProcess cp = do
+  r <- createProcess_ "createProcess" cp
+  maybeCloseStd (std_in  cp)
+  maybeCloseStd (std_out cp)
+  maybeCloseStd (std_err cp)
+  return r
+ where
+  maybeCloseStd :: StdStream -> IO ()
+  maybeCloseStd (UseHandle hdl)
+    | hdl /= stdin && hdl /= stdout && hdl /= stderr = hClose hdl
+  maybeCloseStd _ = return ()
+
+-- | A 'C.bracket'-style resource handler for 'createProcess'.
+--
+-- Does automatic cleanup when the action finishes. If there is an exception
+-- in the body then it ensures that the process gets terminated and any
+-- 'CreatePipe' 'Handle's are closed. In particular this means that if the
+-- Haskell thread is killed (e.g. 'killThread'), that the external process is
+-- also terminated.
+--
+-- e.g.
+--
+-- > withCreateProcess (proc cmd args) { ... }  $ \stdin stdout stderr ph -> do
+-- >   ...
+--
+-- @since 1.4.3.0
+withCreateProcess
+  :: CreateProcess
+  -> (Maybe Handle -> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a)
+  -> IO a
+withCreateProcess c action =
+    C.bracket (createProcess c) cleanupProcess
+              (\(m_in, m_out, m_err, ph) -> action m_in m_out m_err ph)
+
+-- wrapper so we can get exceptions with the appropriate function name.
+withCreateProcess_
+  :: String
+  -> CreateProcess
+  -> (Maybe Handle -> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a)
+  -> IO a
+withCreateProcess_ fun c action =
+    C.bracketOnError (createProcess_ fun c) cleanupProcess
+                     (\(m_in, m_out, m_err, ph) -> action m_in m_out m_err ph)
+
+-- | Cleans up the process.
+--
+-- This function is meant to be invoked from any application level cleanup
+-- handler. It terminates the process, and closes any 'CreatePipe' 'handle's.
+--
+-- @since 1.6.4.0
+cleanupProcess :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
+               -> IO ()
+cleanupProcess (mb_stdin, mb_stdout, mb_stderr,
+                ph@(ProcessHandle _ delegating_ctlc _)) = do
+    terminateProcess ph
+    -- Note, it's important that other threads that might be reading/writing
+    -- these handles also get killed off, since otherwise they might be holding
+    -- the handle lock and prevent us from closing, leading to deadlock.
+    maybe (return ()) (ignoreSigPipe . hClose) mb_stdin
+    maybe (return ()) hClose mb_stdout
+    maybe (return ()) hClose mb_stderr
+    -- terminateProcess does not guarantee that it terminates the process.
+    -- Indeed on Unix it's SIGTERM, which asks nicely but does not guarantee
+    -- that it stops. If it doesn't stop, we don't want to hang, so we wait
+    -- asynchronously using forkIO.
+
+    -- However we want to end the Ctl-C handling synchronously, so we'll do
+    -- that synchronously, and set delegating_ctlc as False for the
+    -- waitForProcess (which would otherwise end the Ctl-C delegation itself).
+    when delegating_ctlc
+      stopDelegateControlC
+    _ <- forkIO (waitForProcess (resetCtlcDelegation ph) >> return ())
+    return ()
+  where
+    resetCtlcDelegation (ProcessHandle m _ l) = ProcessHandle m False l
+
+-- ----------------------------------------------------------------------------
+-- spawnProcess/spawnCommand
+
+-- | Creates a new process to run the specified raw command with the given
+-- arguments. It does not wait for the program to finish, but returns the
+-- 'ProcessHandle'.
+--
+-- @since 1.2.0.0
+spawnProcess :: FilePath -> [String] -> IO ProcessHandle
+spawnProcess cmd args = do
+    (_,_,_,p) <- createProcess_ "spawnProcess" (proc cmd args)
+    return p
+
+-- | Creates a new process to run the specified shell command.
+-- It does not wait for the program to finish, but returns the 'ProcessHandle'.
+--
+-- @since 1.2.0.0
+spawnCommand :: String -> IO ProcessHandle
+spawnCommand cmd = do
+    (_,_,_,p) <- createProcess_ "spawnCommand" (shell cmd)
+    return p
+
+
+-- ----------------------------------------------------------------------------
+-- callProcess/callCommand
+
+-- | Creates a new process from the provided `CreateProcess`, and wait for it
+-- to finish.  If the process returns a non-zero exit code, an exception is
+-- raised.
+--
+-- If an asynchronous exception is thrown to the thread executing
+-- @callCreateProcess@, the forked process will be terminated and
+-- @callCreateProcess@ will wait (block) until the process has been
+-- terminated.
+--
+-- @since TODO
+callCreateProcess :: CreateProcess -> IO ()
+callCreateProcess = callCreateProcess_ "callCreateProcess"
+
+-- | \"@callProcess cmd args@\" is a shorthand for
+-- \"@'callCreateProcess' ('proc' cmd args)@\".
+--
+-- @since 1.2.0.0
+callProcess :: FilePath -> [String] -> IO ()
+callProcess cmd = callCreateProcess_ "callProcess" . proc cmd
+
+-- | \"@callCommand cmd@\" is a shorthand for \"@'callCreateProcess'
+-- ('shell' cmd)@\".
+--
+-- @since 1.2.0.0
+callCommand :: String -> IO ()
+callCommand = callCreateProcess_ "callCommand" . shell
+
+callCreateProcess_ :: String -> CreateProcess -> IO ()
+callCreateProcess_ fun command = do
+    exit_code <- withCreateProcess_ fun
+                   command { delegate_ctlc = True } $ \_ _ _ p ->
+                   waitForProcess p
+    case exit_code of
+      ExitSuccess   -> return ()
+      ExitFailure r -> processFailed fun (cmdspec command) r
+
+processFailed :: String -> CmdSpec -> Int -> IO a
+processFailed fun = \ case
+    ShellCommand cmd -> processFailedException fun cmd []
+    RawCommand cmd args -> processFailedException fun cmd args
+
+processFailedException :: String -> String -> [String] -> Int -> IO a
+processFailedException fun cmd args exit_code =
+      ioError (mkIOError OtherError (fun ++ ": " ++ cmd ++
+                                     concatMap ((' ':) . show) args ++
+                                     " (exit " ++ show exit_code ++ ")")
+                                 Nothing Nothing)
+
+
+-- ----------------------------------------------------------------------------
+-- Secure process creation on Windows
+
+-- $windows-migitations
+--
+-- In general it is strongly advised that any untrusted user input be validated before
+-- being passed to a subprocess. One must be especially careful on Windows due to the
+-- crude nature of the platform's argument passing scheme. Specifically, unlike POSIX
+-- platforms, Windows treats the command-line not as a sequence of arguments but rather
+-- as a single string. It is therefore the responsibility of the called process to tokenize
+-- this string into distinct arguments.
+--
+-- While various programs on Windows tend to differ in their precise argument splitting
+-- behavior, the scheme used by @process@'s 'RawCommand' 'CmdSpec' should work for
+-- most reasonable programs. If you find that 'RawCommand' doesn't provide
+-- the behavior you need, it is recommended to instead compose your command-line
+-- manually and rather using the 'shell' 'CmdSpec'.
+--
+-- Additionally, the idiosyncratic escaping and string interpolation behavior of
+-- the Windows @cmd.exe@ command interpreter is known to introduce considerable
+-- complication to secure process creation. For this reason, @process@ implements
+-- specific argument escaping logic when the executable's file extension suggests
+-- that it is a batch file (e.g. @.bat@ or @.cmd@). However, this is not a
+-- completely reliable mitigation as Windows will also silently execute batch files
+-- when starting executables lacking a file extension (e.g. @callProcess "hello" []@
+-- when a @hello.bat@ is present in @PATH@). For this reason, users are encouraged to
+-- specify the file extension of invoked executables where possible, especially
+-- when untrusted input is involved.
+--
+-- Users passed untrusted input to subprocesses on Windows are encouraged to review
+-- <https://flatt.tech/research/posts/batbadbut-you-cant-securely-execute-commands-on-windows/>
+-- for guidance on how to safely navigate these waters.
+
+-- ----------------------------------------------------------------------------
+-- Control-C handling on Unix
+
+-- $ctlc-handling
+--
+-- When running an interactive console process (such as a shell, console-based
+-- text editor or ghci), we typically want that process to be allowed to handle
+-- Ctl-C keyboard interrupts how it sees fit. For example, while most programs
+-- simply quit on a Ctl-C, some handle it specially. To allow this to happen,
+-- use the @'delegate_ctlc' = True@ option in the 'CreateProcess' options.
+--
+-- The gory details:
+--
+-- By default Ctl-C will generate a @SIGINT@ signal, causing a 'UserInterrupt'
+-- exception to be sent to the main Haskell thread of your program, which if
+-- not specially handled will terminate the program. Normally, this is exactly
+-- what is wanted: an orderly shutdown of the program in response to Ctl-C.
+--
+-- Of course when running another interactive program in the console then we
+-- want to let that program handle Ctl-C. Under Unix however, Ctl-C sends
+-- @SIGINT@ to every process using the console. The standard solution is that
+-- while running an interactive program, ignore @SIGINT@ in the parent, and let
+-- it be handled in the child process. If that process then terminates due to
+-- the @SIGINT@ signal, then at that point treat it as if we had received the
+-- @SIGINT@ ourselves and begin an orderly shutdown.
+--
+-- This behaviour is implemented by 'createProcess' (and
+-- 'waitForProcess' \/ 'getProcessExitCode') when the @'delegate_ctlc' = True@
+-- option is set. In particular, the @SIGINT@ signal will be ignored until
+-- 'waitForProcess' returns (or 'getProcessExitCode' returns a non-Nothing
+-- result), so it becomes especially important to use 'waitForProcess' for every
+-- processes created.
+--
+-- In addition, in 'delegate_ctlc' mode, 'waitForProcess' and
+-- 'getProcessExitCode' will throw a 'UserInterrupt' exception if the process
+-- terminated with @'ExitFailure' (-SIGINT)@. Typically you will not want to
+-- catch this exception, but let it propagate, giving a normal orderly shutdown.
+-- One detail to be aware of is that the 'UserInterrupt' exception is thrown
+-- /synchronously/ in the thread that calls 'waitForProcess', whereas normally
+-- @SIGINT@ causes the exception to be thrown /asynchronously/ to the main
+-- thread.
+--
+-- For even more detail on this topic, see
+-- <http://www.cons.org/cracauer/sigint.html "Proper handling of SIGINT/SIGQUIT">.
+
+-- $exec-on-windows
+--
+-- Note that processes which use the POSIX @exec@ system call (e.g. @gcc@)
+-- require special care on Windows. Specifically, the @msvcrt@ C runtime used
+-- frequently on Windows emulates @exec@ in a non-POSIX compliant manner, where
+-- the caller will be terminated (with exit code 0) and execution will continue
+-- in a new process. As a result, on Windows it will appear as though a child
+-- process which has called @exec@ has terminated despite the fact that the
+-- process would still be running on a POSIX-compliant platform.
+--
+-- Since many programs do use @exec@, the @process@ library exposes the
+-- 'use_process_jobs' flag to make it possible to reliably detect when such a
+-- process completes. When this flag is set a 'ProcessHandle' will not be
+-- deemed to be \"finished\" until all processes spawned by it have
+-- terminated (except those spawned by the child with the
+-- @CREATE_BREAKAWAY_FROM_JOB@ @CreateProcess@ flag).
+--
+-- Note, however, that, because of platform limitations, the exit code returned
+-- by @waitForProcess@ and @getProcessExitCode@ cannot not be relied upon when
+-- the child uses @exec@, even when 'use_process_jobs' is used. Specifically,
+-- these functions will return the exit code of the *original child* (which
+-- always exits with code 0, since it called @exec@), not the exit code of the
+-- process which carried on with execution after @exec@. This is different from
+-- the behavior prescribed by POSIX but is the best approximation that can be
+-- realised under the restrictions of the Windows process model.
+
+-- -----------------------------------------------------------------------------
+
+-- | @readProcess@ forks an external process, reads its standard output
+-- strictly, blocking until the process terminates, and returns the output
+-- string. The external process inherits the standard error.
+--
+-- If an asynchronous exception is thrown to the thread executing
+-- @readProcess@, the forked process will be terminated and @readProcess@ will
+-- wait (block) until the process has been terminated.
+--
+-- Output is returned strictly, so this is not suitable for launching processes
+-- that require interaction over the standard file streams.
+--
+-- This function throws an 'IOError' if the process 'ExitCode' is
+-- anything other than 'ExitSuccess'. If instead you want to get the
+-- 'ExitCode' then use 'readProcessWithExitCode'.
+--
+-- Users of this function should compile with @-threaded@ if they
+-- want other Haskell threads to keep running while waiting on
+-- the result of readProcess.
+--
+-- >  > readProcess "date" [] []
+-- >  "Thu Feb  7 10:03:39 PST 2008\n"
+--
+-- The arguments are:
+--
+-- * The command to run, which must be in the $PATH, or an absolute or relative path
+--
+-- * A list of separate command line arguments to the program.  See 'RawCommand' for
+--   further discussion of Windows semantics.
+--
+-- * A string to pass on standard input to the forked process.
+--
+readProcess
+    :: FilePath                 -- ^ Filename of the executable (see 'RawCommand' for details)
+    -> [String]                 -- ^ any arguments
+    -> String                   -- ^ standard input
+    -> IO String                -- ^ stdout
+readProcess cmd args = readCreateProcess $ proc cmd args
+
+-- | @readCreateProcess@ works exactly like 'readProcess' except that it
+-- lets you pass 'CreateProcess' giving better flexibility.
+--
+-- >  > readCreateProcess ((shell "pwd") { cwd = Just "/etc/" }) ""
+-- >  "/etc\n"
+--
+-- Note that @Handle@s provided for @std_in@ or @std_out@ via the CreateProcess
+-- record will be ignored.
+--
+-- @since 1.2.3.0
+
+readCreateProcess
+    :: CreateProcess
+    -> String                   -- ^ standard input
+    -> IO String                -- ^ stdout
+readCreateProcess cp input = do
+    let cp_opts = cp {
+                    std_in  = CreatePipe,
+                    std_out = CreatePipe
+                  }
+    (ex, output) <- withCreateProcess_ "readCreateProcess" cp_opts $
+      \mb_inh mb_outh _ ph ->
+        case (mb_inh, mb_outh) of
+          (Just inh, Just outh) -> do
+
+            -- fork off a thread to start consuming the output
+            output  <- hGetContents outh
+            withForkWait (C.evaluate $ rnf output) $ \waitOut -> do
+
+              -- now write any input
+              unless (null input) $
+                ignoreSigPipe $ hPutStr inh input
+              -- hClose performs implicit hFlush, and thus may trigger a SIGPIPE
+              ignoreSigPipe $ hClose inh
+
+              -- wait on the output
+              waitOut
+              hClose outh
+
+            -- wait on the process
+            ex <- waitForProcess ph
+            return (ex, output)
+
+          (Nothing,_) -> error "readCreateProcess: Failed to get a stdin handle."
+          (_,Nothing) -> error "readCreateProcess: Failed to get a stdout handle."
+
+    case ex of
+     ExitSuccess   -> return output
+     ExitFailure r -> processFailed "readCreateProcess" (cmdspec cp) r
+
+
+-- | @readProcessWithExitCode@ is like 'readProcess' but with two differences:
+--
+--  * it returns the 'ExitCode' of the process, and does not throw any
+--    exception if the code is not 'ExitSuccess'.
+--
+--  * it reads and returns the output from process' standard error handle,
+--    rather than the process inheriting the standard error handle.
+--
+-- On Unix systems, see 'waitForProcess' for the meaning of exit codes
+-- when the process died as the result of a signal.
+--
+readProcessWithExitCode
+    :: FilePath                 -- ^ Filename of the executable (see 'RawCommand' for details)
+    -> [String]                 -- ^ any arguments
+    -> String                   -- ^ standard input
+    -> IO (ExitCode,String,String) -- ^ exitcode, stdout, stderr
+readProcessWithExitCode cmd args =
+    readCreateProcessWithExitCode $ proc cmd args
+
+-- | @readCreateProcessWithExitCode@ works exactly like 'readProcessWithExitCode' except that it
+-- lets you pass 'CreateProcess' giving better flexibility.
+--
+-- Note that @Handle@s provided for @std_in@, @std_out@, or @std_err@ via the CreateProcess
+-- record will be ignored.
+--
+-- @since 1.2.3.0
+readCreateProcessWithExitCode
+    :: CreateProcess
+    -> String                      -- ^ standard input
+    -> IO (ExitCode,String,String) -- ^ exitcode, stdout, stderr
+readCreateProcessWithExitCode cp input = do
+    let cp_opts = cp {
+                    std_in  = CreatePipe,
+                    std_out = CreatePipe,
+                    std_err = CreatePipe
+                  }
+    withCreateProcess_ "readCreateProcessWithExitCode" cp_opts $
+      \mb_inh mb_outh mb_errh ph ->
+        case (mb_inh, mb_outh, mb_errh) of
+          (Just inh, Just outh, Just errh) -> do
+
+            out <- hGetContents outh
+            err <- hGetContents errh
+
+            -- fork off threads to start consuming stdout & stderr
+            withForkWait  (C.evaluate $ rnf out) $ \waitOut ->
+             withForkWait (C.evaluate $ rnf err) $ \waitErr -> do
+
+              -- now write any input
+              unless (null input) $
+                ignoreSigPipe $ hPutStr inh input
+              -- hClose performs implicit hFlush, and thus may trigger a SIGPIPE
+              ignoreSigPipe $ hClose inh
+
+              -- wait on the output
+              waitOut
+              waitErr
+
+              hClose outh
+              hClose errh
+
+            -- wait on the process
+            ex <- waitForProcess ph
+            return (ex, out, err)
+
+          (Nothing,_,_) -> error "readCreateProcessWithExitCode: Failed to get a stdin handle."
+          (_,Nothing,_) -> error "readCreateProcessWithExitCode: Failed to get a stdout handle."
+          (_,_,Nothing) -> error "readCreateProcessWithExitCode: Failed to get a stderr handle."
+
+-- ----------------------------------------------------------------------------
+-- showCommandForUser
+
+-- | Given a program @/p/@ and arguments @/args/@,
+--   @showCommandForUser /p/ /args/@ returns a string suitable for pasting
+--   into @\/bin\/sh@ (on Unix systems) or @CMD.EXE@ (on Windows).
+showCommandForUser :: FilePath -> [String] -> String
+showCommandForUser cmd args = unwords (map translate (cmd : args))
+
+
+-- ----------------------------------------------------------------------------
+-- getPid
+
+-- | Returns the PID (process ID) of a subprocess.
+--
+-- 'Nothing' is returned if the handle was already closed. Otherwise a
+-- PID is returned that remains valid as long as the handle is open.
+-- The operating system may reuse the PID as soon as the last handle to
+-- the process is closed.
+--
+-- @since 1.6.3.0
+getPid :: ProcessHandle -> IO (Maybe Pid)
+getPid (ProcessHandle mh _ _) = do
+  p_ <- readMVar mh
+  case p_ of
+#if defined(javascript_HOST_ARCH)
+    OpenHandle h -> do
+      pid <- getProcessId h
+      return $ Just pid
+#elif defined(mingw32_HOST_OS)
+    OpenHandle h -> do
+      pid <- getProcessId h
+      return $ Just pid
+#else
+    OpenHandle pid -> return $ Just pid
+#endif
+    _ -> return Nothing
+
+
+-- ----------------------------------------------------------------------------
+-- getCurrentPid
+
+-- | Returns the PID (process ID) of the current process. On POSIX systems,
+-- this calls 'getProcessID' from "System.Posix.Process" in the @unix@ package.
+-- On Windows, this calls 'getCurrentProcessId' from "System.Win32.Process" in
+-- the @Win32@ package.
+--
+-- @since 1.6.12.0
+getCurrentPid :: IO Pid
+getCurrentPid =
+#if defined(javascript_HOST_ARCH)
+    getCurrentProcessId
+#elif defined(mingw32_HOST_OS)
+    getCurrentProcessId
+#else
+    getProcessID
+#endif
+
+
+-- ----------------------------------------------------------------------------
+-- waitForProcess
+
+{- | Waits for the specified process to terminate, and returns its exit code.
+On Unix systems, may throw 'UserInterrupt' when using 'delegate_ctlc'.
+
+GHC Note: in order to call @waitForProcess@ without blocking all the
+other threads in the system, you must compile the program with
+@-threaded@.
+
+Note that it is safe to call @waitForProcess@ for the same process in multiple
+threads. When the process ends, threads blocking on this call will wake in
+FIFO order. When using 'delegate_ctlc' and the process is interrupted, only
+the first waiting thread will throw 'UserInterrupt'.
+
+(/Since: 1.2.0.0/) On Unix systems, a negative value @'ExitFailure' -/signum/@
+indicates that the child was terminated by signal @/signum/@.
+The signal numbers are platform-specific, so to test for a specific signal use
+the constants provided by "System.Posix.Signals" in the @unix@ package.
+Note: core dumps are not reported, use "System.Posix.Process" if you need this
+detail.
+
+-}
+waitForProcess
+  :: ProcessHandle
+  -> IO ExitCode
+waitForProcess ph@(ProcessHandle _ delegating_ctlc _) = lockWaitpid $ do
+  p_ <- modifyProcessHandle ph $ \p_ -> return (p_,p_)
+  case p_ of
+    ClosedHandle e -> return e
+    OpenHandle h  -> do
+        -- don't hold the MVar while we call c_waitForProcess...
+        e <- waitForProcess' h
+        (e', was_open) <- modifyProcessHandle ph $ \p_' ->
+          case p_' of
+            ClosedHandle e' -> return (p_', (e', False))
+            OpenExtHandle{} -> fail "waitForProcess(OpenExtHandle): this cannot happen"
+            OpenHandle ph'  -> do
+              closePHANDLE ph'
+              return (ClosedHandle e, (e, True))
+        -- endDelegateControlC after closing the handle, since it
+        -- may throw UserInterrupt
+        when (was_open && delegating_ctlc) $
+          endDelegateControlC e
+        return e'
+#if defined(mingw32_HOST_OS)
+    OpenExtHandle h job -> do
+        -- First wait for completion of the job...
+        waitForJobCompletion job
+        e <- waitForProcess' h
+        e' <- modifyProcessHandle ph $ \p_' ->
+          case p_' of
+            ClosedHandle e' -> return (p_', e')
+            OpenHandle{}    -> fail "waitForProcess(OpenHandle): this cannot happen"
+            OpenExtHandle ph' job' -> do
+              closePHANDLE ph'
+              closePHANDLE job'
+              return (ClosedHandle e, e)
+        -- omit endDelegateControlC since it's a no-op on Windows
+        return e'
+#else
+    OpenExtHandle _ _job ->
+        return $ ExitFailure (-1)
+#endif
+  where
+    -- If more than one thread calls `waitpid` at a time, `waitpid` will
+    -- return the exit code to one of them and (-1) to the rest of them,
+    -- causing an exception to be thrown.
+    -- Cf. https://github.com/haskell/process/issues/46, and
+    -- https://github.com/haskell/process/pull/58 for further discussion
+    lockWaitpid m = withMVar (waitpidLock ph) $ \() -> m
+
+    waitForProcess' :: PHANDLE -> IO ExitCode
+    waitForProcess' h = alloca $ \pret -> do
+#if defined(javascript_HOST_ARCH)
+      throwErrnoIfMinus1Retry_ "waitForProcess" (C.interruptible $ c_waitForProcess h pret)
+#else
+      throwErrnoIfMinus1Retry_ "waitForProcess" (allowInterrupt >> c_waitForProcess h pret)
+#endif
+      mkExitCode <$> peek pret
+
+    mkExitCode :: CInt -> ExitCode
+    mkExitCode code
+      | code == 0 = ExitSuccess
+      | otherwise = ExitFailure (fromIntegral code)
+
+
+-- ----------------------------------------------------------------------------
+-- getProcessExitCode
+
+{- |
+This is a non-blocking version of 'waitForProcess'.  If the process is
+still running, 'Nothing' is returned.  If the process has exited, then
+@'Just' e@ is returned where @e@ is the exit code of the process.
+
+On Unix systems, see 'waitForProcess' for the meaning of exit codes
+when the process died as the result of a signal. May throw
+'UserInterrupt' when using 'delegate_ctlc'.
+-}
+
+getProcessExitCode :: ProcessHandle -> IO (Maybe ExitCode)
+getProcessExitCode ph@(ProcessHandle _ delegating_ctlc _) = tryLockWaitpid $ do
+  (m_e, was_open) <- modifyProcessHandle ph $ \p_ ->
+    case p_ of
+      ClosedHandle e -> return (p_, (Just e, False))
+      open -> do
+        alloca $ \pExitCode -> do
+          case getHandle open of
+            Nothing -> return (p_, (Nothing, False))
+            Just h  -> do
+                res <- throwErrnoIfMinus1Retry "getProcessExitCode" $
+                                        c_getProcessExitCode h pExitCode
+                code <- peek pExitCode
+                if res == 0
+                   then return (p_, (Nothing, False))
+                   else do
+                        closePHANDLE h
+                        let e  | code == 0 = ExitSuccess
+                               | otherwise = ExitFailure (fromIntegral code)
+                        return (ClosedHandle e, (Just e, True))
+  -- endDelegateControlC after closing the handle, since it
+  -- may throw UserInterrupt
+  case m_e of
+    Just e | was_open && delegating_ctlc -> endDelegateControlC e
+    _                                    -> return ()
+  return m_e
+    where getHandle :: ProcessHandle__ -> Maybe PHANDLE
+          getHandle (OpenHandle        h) = Just h
+          getHandle (ClosedHandle      _) = Nothing
+          getHandle (OpenExtHandle   h _) = Just h
+
+          -- If somebody is currently holding the waitpid lock, we don't want to
+          -- accidentally remove the pid from the process table.
+          -- Try acquiring the waitpid lock. If it is held, we are done
+          -- since that means the process is still running and we can return
+          -- `Nothing`. If it is not held, acquire it so we can run the
+          -- (non-blocking) call to `waitpid` without worrying about any
+          -- other threads calling it at the same time.
+          tryLockWaitpid :: IO (Maybe ExitCode) -> IO (Maybe ExitCode)
+          tryLockWaitpid action = bracket acquire release between
+            where
+              acquire   = tryTakeMVar (waitpidLock ph)
+              release m = case m of
+                Nothing -> return ()
+                Just () -> putMVar (waitpidLock ph) ()
+              between m = case m of
+                Nothing -> return Nothing
+                Just () -> action
+
+-- ----------------------------------------------------------------------------
+-- terminateProcess
+
+-- | Attempts to terminate the specified process.  This function should
+-- not be used under normal circumstances - no guarantees are given regarding
+-- how cleanly the process is terminated.  To check whether the process
+-- has indeed terminated, use 'getProcessExitCode'.
+--
+-- On Unix systems, 'terminateProcess' sends the process the SIGTERM signal.
+-- On Windows systems, if `use_process_jobs` is `True` then the Win32 @TerminateJobObject@
+-- function is called to kill all processes associated with the job and passing the
+-- exit code of 1 to each of them. Otherwise if `use_process_jobs` is `False` then the
+-- Win32 @TerminateProcess@ function is called, passing an exit code of 1.
+--
+-- Note: on Windows, if the process was a shell command created by
+-- 'createProcess' with 'shell', or created by 'runCommand' or
+-- 'runInteractiveCommand', then 'terminateProcess' will only
+-- terminate the shell, not the command itself.  On Unix systems, both
+-- processes are in a process group and will be terminated together.
+
+terminateProcess :: ProcessHandle -> IO ()
+terminateProcess ph = do
+  withProcessHandle ph $ \p_ ->
+    case p_ of
+      ClosedHandle  _ -> return ()
+#if defined(mingw32_HOST_OS)
+      OpenExtHandle{} -> terminateJobUnsafe p_ 1 >> return ()
+#else
+      OpenExtHandle{} -> error "terminateProcess with OpenExtHandle should not happen on POSIX."
+#endif
+      OpenHandle    h -> do
+        throwErrnoIfMinus1Retry_ "terminateProcess" $ c_terminateProcess h
+        return ()
+        -- does not close the handle, we might want to try terminating it
+        -- again, or get its exit code.
+
+
+-- ----------------------------------------------------------------------------
+-- Interface to C bits
+
+#if defined(wasm32_HOST_ARCH)
+
+c_terminateProcess :: PHANDLE -> IO CInt
+c_terminateProcess _ = ioError (ioeSetLocation unsupportedOperation "terminateProcess")
+
+c_getProcessExitCode :: PHANDLE -> Ptr CInt -> IO CInt
+c_getProcessExitCode _ _ = ioError (ioeSetLocation unsupportedOperation "getProcessExitCode")
+
+c_waitForProcess :: PHANDLE -> Ptr CInt -> IO CInt
+c_waitForProcess _ _ = ioError (ioeSetLocation unsupportedOperation "waitForProcess")
+
+#elif defined(javascript_HOST_ARCH)
+
+foreign import javascript unsafe "h$process_terminateProcess"
+  c_terminateProcess
+        :: PHANDLE
+        -> IO Int
+
+foreign import javascript unsafe "h$process_getProcessExitCode"
+  c_getProcessExitCode
+        :: PHANDLE
+        -> Ptr Int
+        -> IO Int
+
+foreign import javascript interruptible "h$process_waitForProcess"
+  c_waitForProcess
+        :: PHANDLE
+        -> Ptr CInt
+        -> IO CInt
+
+#else
+
+foreign import ccall unsafe "terminateProcess"
+  c_terminateProcess
+        :: PHANDLE
+        -> IO CInt
+
+foreign import ccall unsafe "getProcessExitCode"
+  c_getProcessExitCode
+        :: PHANDLE
+        -> Ptr CInt
+        -> IO CInt
+
+foreign import ccall interruptible "waitForProcess" -- NB. safe - can block
+  c_waitForProcess
+        :: PHANDLE
+        -> Ptr CInt
+        -> IO CInt
+
+#endif
+
+-- ----------------------------------------------------------------------------
+-- Old deprecated variants
+-- ----------------------------------------------------------------------------
+
+-- TODO: We're not going to mark these functions as DEPRECATED immediately in
+-- process-1.2.0.0. That's because some of their replacements have not been
+-- around for all that long. But they should eventually be marked with a
+-- suitable DEPRECATED pragma after a release or two.
+
+
+-- ----------------------------------------------------------------------------
+-- runCommand
+
+--TODO: in a later release {-# DEPRECATED runCommand "Use 'spawnCommand' instead" #-}
+
+{- | Runs a command using the shell.
+ -}
+runCommand
+  :: String
+  -> IO ProcessHandle
+
+runCommand string = do
+  (_,_,_,ph) <- createProcess_ "runCommand" (shell string)
+  return ph
+
+
+-- ----------------------------------------------------------------------------
+-- runProcess
+
+--TODO: in a later release {-# DEPRECATED runProcess "Use 'spawnProcess' or 'createProcess' instead" #-}
+
+{- | Runs a raw command, optionally specifying 'Handle's from which to
+     take the @stdin@, @stdout@ and @stderr@ channels for the new
+     process (otherwise these handles are inherited from the current
+     process).
+
+     Any 'Handle's passed to 'runProcess' are placed immediately in the
+     closed state.
+
+     Note: consider using the more general 'createProcess' instead of
+     'runProcess'.
+-}
+runProcess
+  :: FilePath                   -- ^ Filename of the executable (see 'RawCommand' for details)
+  -> [String]                   -- ^ Arguments to pass to the executable
+  -> Maybe FilePath             -- ^ Optional path to the working directory
+  -> Maybe [(String,String)]    -- ^ Optional environment (otherwise inherit)
+  -> Maybe Handle               -- ^ Handle to use for @stdin@ (Nothing => use existing @stdin@)
+  -> Maybe Handle               -- ^ Handle to use for @stdout@ (Nothing => use existing @stdout@)
+  -> Maybe Handle               -- ^ Handle to use for @stderr@ (Nothing => use existing @stderr@)
+  -> IO ProcessHandle
+
+runProcess cmd args mb_cwd mb_env mb_stdin mb_stdout mb_stderr = do
+  (_,_,_,ph) <-
+      createProcess_ "runProcess"
+         (proc cmd args){ cwd = mb_cwd,
+                          env = mb_env,
+                          std_in  = mbToStd mb_stdin,
+                          std_out = mbToStd mb_stdout,
+                          std_err = mbToStd mb_stderr }
+  maybeClose mb_stdin
+  maybeClose mb_stdout
+  maybeClose mb_stderr
+  return ph
+ where
+  maybeClose :: Maybe Handle -> IO ()
+  maybeClose (Just  hdl)
+    | hdl /= stdin && hdl /= stdout && hdl /= stderr = hClose hdl
+  maybeClose _ = return ()
+
+  mbToStd :: Maybe Handle -> StdStream
+  mbToStd Nothing    = Inherit
+  mbToStd (Just hdl) = UseHandle hdl
+
+
+-- ----------------------------------------------------------------------------
+-- runInteractiveCommand
+
+--TODO: in a later release {-# DEPRECATED runInteractiveCommand "Use 'createProcess' instead" #-}
+
+{- | Runs a command using the shell, and returns 'Handle's that may
+     be used to communicate with the process via its @stdin@, @stdout@,
+     and @stderr@ respectively.
+-}
+runInteractiveCommand
+  :: String
+  -> IO (Handle,Handle,Handle,ProcessHandle)
+
+runInteractiveCommand string =
+  runInteractiveProcess1 "runInteractiveCommand" (shell string)
+
+
+-- ----------------------------------------------------------------------------
+-- runInteractiveProcess
+
+--TODO: in a later release {-# DEPRECATED runInteractiveCommand "Use 'createProcess' instead" #-}
+
+{- | Runs a raw command, and returns 'Handle's that may be used to communicate
+     with the process via its @stdin@, @stdout@ and @stderr@ respectively.
+
+    For example, to start a process and feed a string to its stdin:
+
+>   (inp,out,err,pid) <- runInteractiveProcess "..."
+>   forkIO (hPutStr inp str)
+-}
+runInteractiveProcess
+  :: FilePath                   -- ^ Filename of the executable (see 'RawCommand' for details)
+  -> [String]                   -- ^ Arguments to pass to the executable
+  -> Maybe FilePath             -- ^ Optional path to the working directory
+  -> Maybe [(String,String)]    -- ^ Optional environment (otherwise inherit)
+  -> IO (Handle,Handle,Handle,ProcessHandle)
+
+runInteractiveProcess cmd args mb_cwd mb_env = do
+  runInteractiveProcess1 "runInteractiveProcess"
+        (proc cmd args){ cwd = mb_cwd, env = mb_env }
+
+runInteractiveProcess1
+  :: String
+  -> CreateProcess
+  -> IO (Handle,Handle,Handle,ProcessHandle)
+runInteractiveProcess1 fun cmd = do
+  (mb_in, mb_out, mb_err, p) <-
+      createProcess_ fun
+           cmd{ std_in  = CreatePipe,
+                std_out = CreatePipe,
+                std_err = CreatePipe }
+  return (fromJust mb_in, fromJust mb_out, fromJust mb_err, p)
+
+
+-- ---------------------------------------------------------------------------
+-- system & rawSystem
+
+--TODO: in a later release {-# DEPRECATED system "Use 'callCommand' (or 'spawnCommand' and 'waitForProcess') instead" #-}
+
+{-|
+Computation @system cmd@ returns the exit code produced when the
+operating system runs the shell command @cmd@.
+
+This computation may fail with one of the following
+'System.IO.Error.IOErrorType' exceptions:
+
+[@PermissionDenied@]
+The process has insufficient privileges to perform the operation.
+
+[@ResourceExhausted@]
+Insufficient resources are available to perform the operation.
+
+[@UnsupportedOperation@]
+The implementation does not support system calls.
+
+On Windows, 'system' passes the command to the Windows command
+interpreter (@CMD.EXE@ or @COMMAND.COM@), hence Unixy shell tricks
+will not work.
+
+On Unix systems, see 'waitForProcess' for the meaning of exit codes
+when the process died as the result of a signal.
+-}
+system :: String -> IO ExitCode
+system "" = ioException (ioeSetErrorString (mkIOError InvalidArgument "system" Nothing Nothing) "null command")
+system str = do
+  (_,_,_,p) <- createProcess_ "system" (shell str) { delegate_ctlc = True }
+  waitForProcess p
+
+
+--TODO: in a later release {-# DEPRECATED rawSystem "Use 'callProcess' (or 'spawnProcess' and 'waitForProcess') instead" #-}
+
+{-|
+The computation @'rawSystem' /cmd/ /args/@ runs the operating system command
+@/cmd/@ in such a way that it receives as arguments the @/args/@ strings
+exactly as given, with no funny escaping or shell meta-syntax expansion.
+It will therefore behave more portably between operating systems than 'system'.
+
+The return codes and possible failures are the same as for 'system'.
+-}
+rawSystem :: String -> [String] -> IO ExitCode
+rawSystem cmd args = do
+  (_,_,_,p) <- createProcess_ "rawSystem" (proc cmd args) { delegate_ctlc = True }
+  waitForProcess p
diff --git a/System/Process.hsc b/System/Process.hsc
deleted file mode 100644
--- a/System/Process.hsc
+++ /dev/null
@@ -1,964 +0,0 @@
-{-# LANGUAGE CPP, ForeignFunctionInterface #-}
-#ifdef __GLASGOW_HASKELL__
-#if __GLASGOW_HASKELL__ >= 709
-{-# LANGUAGE Safe #-}
-#else
-{-# LANGUAGE Trustworthy #-}
-#endif
-{-# LANGUAGE InterruptibleFFI #-}
-#endif
-
------------------------------------------------------------------------------
--- |
--- Module      :  System.Process
--- Copyright   :  (c) The University of Glasgow 2004-2008
--- License     :  BSD-style (see the file libraries/base/LICENSE)
---
--- Maintainer  :  libraries@haskell.org
--- Stability   :  experimental
--- Portability :  non-portable (requires concurrency)
---
--- Operations for creating and interacting with sub-processes.
---
------------------------------------------------------------------------------
-
--- ToDo:
---      * Flag to control whether exiting the parent also kills the child.
-
-module System.Process (
-    -- * Running sub-processes
-    createProcess,
-    createProcess_,
-    shell, proc,
-    CreateProcess(..),
-    CmdSpec(..),
-    StdStream(..),
-    ProcessHandle,
-
-    -- ** Simpler functions for common tasks
-    callProcess,
-    callCommand,
-    spawnProcess,
-    spawnCommand,
-    readCreateProcess,
-    readProcess,
-    readCreateProcessWithExitCode,
-    readProcessWithExitCode,
-
-    -- ** Related utilities
-    showCommandForUser,
-
-    -- ** Control-C handling on Unix
-    -- $ctlc-handling
-
-    -- * Process completion
-    waitForProcess,
-    getProcessExitCode,
-    terminateProcess,
-    interruptProcessGroupOf,
-
-    -- Interprocess communication
-    createPipe,
-
-    -- * Old deprecated functions
-    -- | These functions pre-date 'createProcess' which is much more
-    -- flexible.
-    runProcess,
-    runCommand,
-    runInteractiveProcess,
-    runInteractiveCommand,
-    system,
-    rawSystem,
-    ) where
-
-import Prelude hiding (mapM)
-
-import System.Process.Internals
-
-import Control.Concurrent
-import Control.DeepSeq (rnf)
-import Control.Exception (SomeException, mask, try, throwIO)
-import qualified Control.Exception as C
-import Control.Monad
-import Data.Maybe
-import Foreign
-import Foreign.C
-import System.Exit      ( ExitCode(..) )
-import System.IO
-import System.IO.Error (mkIOError, ioeSetErrorString)
-
-#if defined(mingw32_HOST_OS)
-# include <io.h>        /* for _close and _pipe */
-# include <fcntl.h>     /* for _O_BINARY */
-import Control.Exception (onException)
-#else
-import System.Posix.Process (getProcessGroupIDOf)
-import qualified System.Posix.IO as Posix
-import System.Posix.Types
-#endif
-
-#ifdef __GLASGOW_HASKELL__
-import GHC.IO.Exception ( ioException, IOErrorType(..), IOException(..) )
-# if defined(mingw32_HOST_OS)
-import System.Win32.Console (generateConsoleCtrlEvent, cTRL_BREAK_EVENT)
-import System.Win32.Process (getProcessId)
-# else
-import System.Posix.Signals
-# endif
-#endif
-
--- ----------------------------------------------------------------------------
--- createProcess
-
--- | Construct a 'CreateProcess' record for passing to 'createProcess',
--- representing a raw command with arguments.
---
--- See 'RawCommand' for precise semantics of the specified @FilePath@.
-proc :: FilePath -> [String] -> CreateProcess
-proc cmd args = CreateProcess { cmdspec = RawCommand cmd args,
-                                cwd = Nothing,
-                                env = Nothing,
-                                std_in = Inherit,
-                                std_out = Inherit,
-                                std_err = Inherit,
-                                close_fds = False,
-                                create_group = False,
-                                delegate_ctlc = False,
-                                detach_console = False,
-                                create_new_console = False,
-                                new_session = False }
-
--- | Construct a 'CreateProcess' record for passing to 'createProcess',
--- representing a command to be passed to the shell.
-shell :: String -> CreateProcess
-shell str = CreateProcess { cmdspec = ShellCommand str,
-                            cwd = Nothing,
-                            env = Nothing,
-                            std_in = Inherit,
-                            std_out = Inherit,
-                            std_err = Inherit,
-                            close_fds = False,
-                            create_group = False,
-                            delegate_ctlc = False,
-                            detach_console = False,
-                            create_new_console = False,
-                            new_session = False }
-
-{- |
-This is the most general way to spawn an external process.  The
-process can be a command line to be executed by a shell or a raw command
-with a list of arguments.  The stdin, stdout, and stderr streams of
-the new process may individually be attached to new pipes, to existing
-'Handle's, or just inherited from the parent (the default.)
-
-The details of how to create the process are passed in the
-'CreateProcess' record.  To make it easier to construct a
-'CreateProcess', the functions 'proc' and 'shell' are supplied that
-fill in the fields with default values which can be overriden as
-needed.
-
-'createProcess' returns @(/mb_stdin_hdl/, /mb_stdout_hdl/, /mb_stderr_hdl/, /ph/)@,
-where
-
- * if @'std_in' == 'CreatePipe'@, then @/mb_stdin_hdl/@ will be @Just /h/@,
-   where @/h/@ is the write end of the pipe connected to the child
-   process's @stdin@.
-
- * otherwise, @/mb_stdin_hdl/ == Nothing@
-
-Similarly for @/mb_stdout_hdl/@ and @/mb_stderr_hdl/@.
-
-For example, to execute a simple @ls@ command:
-
->   r <- createProcess (proc "ls" [])
-
-To create a pipe from which to read the output of @ls@:
-
->   (_, Just hout, _, _) <-
->       createProcess (proc "ls" []){ std_out = CreatePipe }
-
-To also set the directory in which to run @ls@:
-
->   (_, Just hout, _, _) <-
->       createProcess (proc "ls" []){ cwd = Just "\home\bob",
->                                     std_out = CreatePipe }
-
-Note that @Handle@s provided for @std_in@, @std_out@, or @std_err@ via the
-@UseHandle@ constructor will be closed by calling this function. This is not
-always the desired behavior. In cases where you would like to leave the
-@Handle@ open after spawning the child process, please use 'createProcess_'
-instead.
-
--}
-createProcess
-  :: CreateProcess
-  -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
-createProcess cp = do
-  r <- createProcess_ "createProcess" cp
-  maybeCloseStd (std_in  cp)
-  maybeCloseStd (std_out cp)
-  maybeCloseStd (std_err cp)
-  return r
- where
-  maybeCloseStd :: StdStream -> IO ()
-  maybeCloseStd (UseHandle hdl)
-    | hdl /= stdin && hdl /= stdout && hdl /= stderr = hClose hdl
-  maybeCloseStd _ = return ()
-
-{-
--- TODO: decide if we want to expose this to users
--- | A 'C.bracketOnError'-style resource handler for 'createProcess'.
---
--- In normal operation it adds nothing, you are still responsible for waiting
--- for (or forcing) process termination and closing any 'Handle's. It only does
--- automatic cleanup if there is an exception. If there is an exception in the
--- body then it ensures that the process gets terminated and any 'CreatePipe'
--- 'Handle's are closed. In particular this means that if the Haskell thread
--- is killed (e.g. 'killThread'), that the external process is also terminated.
---
--- e.g.
---
--- > withCreateProcess (proc cmd args) { ... }  $ \_ _ _ ph -> do
--- >   ...
---
-withCreateProcess
-  :: CreateProcess
-  -> (Maybe Handle -> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a)
-  -> IO a
-withCreateProcess c action =
-    C.bracketOnError (createProcess c) cleanupProcess
-                     (\(m_in, m_out, m_err, ph) -> action m_in m_out m_err ph)
--}
-
--- wrapper so we can get exceptions with the appropriate function name.
-withCreateProcess_
-  :: String
-  -> CreateProcess
-  -> (Maybe Handle -> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a)
-  -> IO a
-withCreateProcess_ fun c action =
-    C.bracketOnError (createProcess_ fun c) cleanupProcess
-                     (\(m_in, m_out, m_err, ph) -> action m_in m_out m_err ph)
-
-
-cleanupProcess :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
-               -> IO ()
-cleanupProcess (mb_stdin, mb_stdout, mb_stderr,
-                ph@(ProcessHandle _ delegating_ctlc)) = do
-    terminateProcess ph
-    -- Note, it's important that other threads that might be reading/writing
-    -- these handles also get killed off, since otherwise they might be holding
-    -- the handle lock and prevent us from closing, leading to deadlock.
-    maybe (return ()) (ignoreSigPipe . hClose) mb_stdin
-    maybe (return ()) hClose mb_stdout
-    maybe (return ()) hClose mb_stderr
-    -- terminateProcess does not guarantee that it terminates the process.
-    -- Indeed on Unix it's SIGTERM, which asks nicely but does not guarantee
-    -- that it stops. If it doesn't stop, we don't want to hang, so we wait
-    -- asynchronously using forkIO.
-
-    -- However we want to end the Ctl-C handling synchronously, so we'll do
-    -- that synchronously, and set delegating_ctlc as False for the
-    -- waitForProcess (which would otherwise end the Ctl-C delegation itself).
-    when delegating_ctlc
-      stopDelegateControlC
-    _ <- forkIO (waitForProcess (resetCtlcDelegation ph) >> return ())
-    return ()
-  where
-    resetCtlcDelegation (ProcessHandle m _) = ProcessHandle m False
-
--- ----------------------------------------------------------------------------
--- spawnProcess/spawnCommand
-
--- | Creates a new process to run the specified raw command with the given
--- arguments. It does not wait for the program to finish, but returns the
--- 'ProcessHandle'.
---
--- @since 1.2.0.0
-spawnProcess :: FilePath -> [String] -> IO ProcessHandle
-spawnProcess cmd args = do
-    (_,_,_,p) <- createProcess_ "spawnProcess" (proc cmd args)
-    return p
-
--- | Creates a new process to run the specified shell command.
--- It does not wait for the program to finish, but returns the 'ProcessHandle'.
---
--- @since 1.2.0.0
-spawnCommand :: String -> IO ProcessHandle
-spawnCommand cmd = do
-    (_,_,_,p) <- createProcess_ "spawnCommand" (shell cmd)
-    return p
-
-
--- ----------------------------------------------------------------------------
--- callProcess/callCommand
-
--- | Creates a new process to run the specified command with the given
--- arguments, and wait for it to finish.  If the command returns a non-zero
--- exit code, an exception is raised.
---
--- If an asynchronous exception is thrown to the thread executing
--- @callProcess@. The forked process will be terminated and
--- @callProcess@ will wait (block) until the process has been
--- terminated.
---
--- @since 1.2.0.0
-callProcess :: FilePath -> [String] -> IO ()
-callProcess cmd args = do
-    exit_code <- withCreateProcess_ "callProcess"
-                   (proc cmd args) { delegate_ctlc = True } $ \_ _ _ p ->
-                   waitForProcess p
-    case exit_code of
-      ExitSuccess   -> return ()
-      ExitFailure r -> processFailedException "callProcess" cmd args r
-
--- | Creates a new process to run the specified shell command.  If the
--- command returns a non-zero exit code, an exception is raised.
---
--- If an asynchronous exception is thrown to the thread executing
--- @callCommand@. The forked process will be terminated and
--- @callCommand@ will wait (block) until the process has been
--- terminated.
---
--- @since 1.2.0.0
-callCommand :: String -> IO ()
-callCommand cmd = do
-    exit_code <- withCreateProcess_ "callCommand"
-                   (shell cmd) { delegate_ctlc = True } $ \_ _ _ p ->
-                   waitForProcess p
-    case exit_code of
-      ExitSuccess   -> return ()
-      ExitFailure r -> processFailedException "callCommand" cmd [] r
-
-processFailedException :: String -> String -> [String] -> Int -> IO a
-processFailedException fun cmd args exit_code =
-      ioError (mkIOError OtherError (fun ++ ": " ++ cmd ++
-                                     concatMap ((' ':) . show) args ++
-                                     " (exit " ++ show exit_code ++ ")")
-                                 Nothing Nothing)
-
-
--- ----------------------------------------------------------------------------
--- Control-C handling on Unix
-
--- $ctlc-handling
---
--- When running an interactive console process (such as a shell, console-based
--- text editor or ghci), we typically want that process to be allowed to handle
--- Ctl-C keyboard interrupts how it sees fit. For example, while most programs
--- simply quit on a Ctl-C, some handle it specially. To allow this to happen,
--- use the @'delegate_ctlc' = True@ option in the 'CreateProcess' options.
---
--- The gory details:
---
--- By default Ctl-C will generate a @SIGINT@ signal, causing a 'UserInterrupt'
--- exception to be sent to the main Haskell thread of your program, which if
--- not specially handled will terminate the program. Normally, this is exactly
--- what is wanted: an orderly shutdown of the program in response to Ctl-C.
---
--- Of course when running another interactive program in the console then we
--- want to let that program handle Ctl-C. Under Unix however, Ctl-C sends
--- @SIGINT@ to every process using the console. The standard solution is that
--- while running an interactive program, ignore @SIGINT@ in the parent, and let
--- it be handled in the child process. If that process then terminates due to
--- the @SIGINT@ signal, then at that point treat it as if we had recieved the
--- @SIGINT@ ourselves and begin an orderly shutdown.
---
--- This behaviour is implemented by 'createProcess' (and
--- 'waitForProcess' \/ 'getProcessExitCode') when the @'delegate_ctlc' = True@
--- option is set. In particular, the @SIGINT@ signal will be ignored until
--- 'waitForProcess' returns (or 'getProcessExitCode' returns a non-Nothing
--- result), so it becomes especially important to use 'waitForProcess' for every
--- processes created.
---
--- In addition, in 'delegate_ctlc' mode, 'waitForProcess' and
--- 'getProcessExitCode' will throw a 'UserInterrupt' exception if the process
--- terminated with @'ExitFailure' (-SIGINT)@. Typically you will not want to
--- catch this exception, but let it propagate, giving a normal orderly shutdown.
--- One detail to be aware of is that the 'UserInterrupt' exception is thrown
--- /synchronously/ in the thread that calls 'waitForProcess', whereas normally
--- @SIGINT@ causes the exception to be thrown /asynchronously/ to the main
--- thread.
---
--- For even more detail on this topic, see
--- <http://www.cons.org/cracauer/sigint.html "Proper handling of SIGINT/SIGQUIT">.
-
--- -----------------------------------------------------------------------------
-
--- | @readProcess@ forks an external process, reads its standard output
--- strictly, blocking until the process terminates, and returns the output
--- string. The external process inherits the standard error.
---
--- If an asynchronous exception is thrown to the thread executing
--- @readProcess@, the forked process will be terminated and @readProcess@ will
--- wait (block) until the process has been terminated.
---
--- Output is returned strictly, so this is not suitable for
--- interactive applications.
---
--- This function throws an 'IOError' if the process 'ExitCode' is
--- anything other than 'ExitSuccess'. If instead you want to get the
--- 'ExitCode' then use 'readProcessWithExitCode'.
---
--- Users of this function should compile with @-threaded@ if they
--- want other Haskell threads to keep running while waiting on
--- the result of readProcess.
---
--- >  > readProcess "date" [] []
--- >  "Thu Feb  7 10:03:39 PST 2008\n"
---
--- The arguments are:
---
--- * The command to run, which must be in the $PATH, or an absolute or relative path
---
--- * A list of separate command line arguments to the program
---
--- * A string to pass on standard input to the forked process.
---
-readProcess
-    :: FilePath                 -- ^ Filename of the executable (see 'RawCommand' for details)
-    -> [String]                 -- ^ any arguments
-    -> String                   -- ^ standard input
-    -> IO String                -- ^ stdout
-readProcess cmd args = readCreateProcess $ proc cmd args
-
--- | @readCreateProcess@ works exactly like 'readProcess' except that it
--- lets you pass 'CreateProcess' giving better flexibility.
---
--- >  > readCreateProcess (shell "pwd" { cwd = "/etc/" }) ""
--- >  "/etc\n"
---
--- Note that @Handle@s provided for @std_in@ or @std_out@ via the CreateProcess
--- record will be ignored.
--- @since 1.2.3.0
-
-readCreateProcess
-    :: CreateProcess
-    -> String                   -- ^ standard input
-    -> IO String                -- ^ stdout
-readCreateProcess cp input = do
-    let cp_opts = cp {
-                    std_in  = CreatePipe,
-                    std_out = CreatePipe
-                  }
-    (ex, output) <- withCreateProcess_ "readCreateProcess" cp_opts $
-      \(Just inh) (Just outh) _ ph -> do
-
-        -- fork off a thread to start consuming the output
-        output  <- hGetContents outh
-        withForkWait (C.evaluate $ rnf output) $ \waitOut -> do
-
-          -- now write any input
-          unless (null input) $
-            ignoreSigPipe $ hPutStr inh input
-          -- hClose performs implicit hFlush, and thus may trigger a SIGPIPE
-          ignoreSigPipe $ hClose inh
-
-          -- wait on the output
-          waitOut
-          hClose outh
-
-        -- wait on the process
-        ex <- waitForProcess ph
-        return (ex, output)
-
-    case ex of
-     ExitSuccess   -> return output
-     ExitFailure r -> processFailedException "readCreateProcess" cmd args r
-  where
-    cmd = case cp of
-            CreateProcess { cmdspec = ShellCommand sc } -> sc
-            CreateProcess { cmdspec = RawCommand fp _ } -> fp
-    args = case cp of
-             CreateProcess { cmdspec = ShellCommand _ } -> []
-             CreateProcess { cmdspec = RawCommand _ args' } -> args'
-
-
--- | @readProcessWithExitCode@ is like @readProcess@ but with two differences:
---
---  * it returns the 'ExitCode' of the process, and does not throw any
---    exception if the code is not 'ExitSuccess'.
---
---  * it reads and returns the output from process' standard error handle,
---    rather than the process inheriting the standard error handle.
---
--- On Unix systems, see 'waitForProcess' for the meaning of exit codes
--- when the process died as the result of a signal.
---
-readProcessWithExitCode
-    :: FilePath                 -- ^ Filename of the executable (see 'RawCommand' for details)
-    -> [String]                 -- ^ any arguments
-    -> String                   -- ^ standard input
-    -> IO (ExitCode,String,String) -- ^ exitcode, stdout, stderr
-readProcessWithExitCode cmd args =
-    readCreateProcessWithExitCode $ proc cmd args
-
--- | @readCreateProcessWithExitCode@ works exactly like 'readProcessWithExitCode' except that it
--- lets you pass 'CreateProcess' giving better flexibility.
---
--- Note that @Handle@s provided for @std_in@, @std_out@, or @std_err@ via the CreateProcess
--- record will be ignored.
---
--- @since 1.2.3.0
-readCreateProcessWithExitCode
-    :: CreateProcess
-    -> String                      -- ^ standard input
-    -> IO (ExitCode,String,String) -- ^ exitcode, stdout, stderr
-readCreateProcessWithExitCode cp input = do
-    let cp_opts = cp {
-                    std_in  = CreatePipe,
-                    std_out = CreatePipe,
-                    std_err = CreatePipe
-                  }
-    withCreateProcess_ "readCreateProcessWithExitCode" cp_opts $
-      \(Just inh) (Just outh) (Just errh) ph -> do
-
-        out <- hGetContents outh
-        err <- hGetContents errh
-
-        -- fork off threads to start consuming stdout & stderr
-        withForkWait  (C.evaluate $ rnf out) $ \waitOut ->
-         withForkWait (C.evaluate $ rnf err) $ \waitErr -> do
-
-          -- now write any input
-          unless (null input) $
-            ignoreSigPipe $ hPutStr inh input
-          -- hClose performs implicit hFlush, and thus may trigger a SIGPIPE
-          ignoreSigPipe $ hClose inh
-
-          -- wait on the output
-          waitOut
-          waitErr
-
-          hClose outh
-          hClose errh
-
-        -- wait on the process
-        ex <- waitForProcess ph
-
-        return (ex, out, err)
-
--- | Fork a thread while doing something else, but kill it if there's an
--- exception.
---
--- This is important in the cases above because we want to kill the thread
--- that is holding the Handle lock, because when we clean up the process we
--- try to close that handle, which could otherwise deadlock.
---
-withForkWait :: IO () -> (IO () ->  IO a) -> IO a
-withForkWait async body = do
-  waitVar <- newEmptyMVar :: IO (MVar (Either SomeException ()))
-  mask $ \restore -> do
-    tid <- forkIO $ try (restore async) >>= putMVar waitVar
-    let wait = takeMVar waitVar >>= either throwIO return
-    restore (body wait) `C.onException` killThread tid
-
-ignoreSigPipe :: IO () -> IO ()
-#if defined(__GLASGOW_HASKELL__)
-ignoreSigPipe = C.handle $ \e -> case e of
-                                   IOError { ioe_type  = ResourceVanished
-                                           , ioe_errno = Just ioe }
-                                     | Errno ioe == ePIPE -> return ()
-                                   _ -> throwIO e
-#else
-ignoreSigPipe = id
-#endif
-
--- ----------------------------------------------------------------------------
--- showCommandForUser
-
--- | Given a program @/p/@ and arguments @/args/@,
---   @showCommandForUser /p/ /args/@ returns a string suitable for pasting
---   into @\/bin\/sh@ (on Unix systems) or @CMD.EXE@ (on Windows).
-showCommandForUser :: FilePath -> [String] -> String
-showCommandForUser cmd args = unwords (map translate (cmd : args))
-
-
--- ----------------------------------------------------------------------------
--- waitForProcess
-
-{- | Waits for the specified process to terminate, and returns its exit code.
-
-GHC Note: in order to call @waitForProcess@ without blocking all the
-other threads in the system, you must compile the program with
-@-threaded@.
-
-(/Since: 1.2.0.0/) On Unix systems, a negative value @'ExitFailure' -/signum/@
-indicates that the child was terminated by signal @/signum/@.
-The signal numbers are platform-specific, so to test for a specific signal use
-the constants provided by "System.Posix.Signals" in the @unix@ package.
-Note: core dumps are not reported, use "System.Posix.Process" if you need this
-detail.
-
--}
-waitForProcess
-  :: ProcessHandle
-  -> IO ExitCode
-waitForProcess ph@(ProcessHandle _ delegating_ctlc) = do
-  p_ <- modifyProcessHandle ph $ \p_ -> return (p_,p_)
-  case p_ of
-    ClosedHandle e -> return e
-    OpenHandle h  -> do
-        -- don't hold the MVar while we call c_waitForProcess...
-        -- (XXX but there's a small race window here during which another
-        -- thread could close the handle or call waitForProcess)
-        e <- alloca $ \pret -> do
-          throwErrnoIfMinus1Retry_ "waitForProcess" (c_waitForProcess h pret)
-          modifyProcessHandle ph $ \p_' ->
-            case p_' of
-              ClosedHandle e -> return (p_',e)
-              OpenHandle ph' -> do
-                closePHANDLE ph'
-                code <- peek pret
-                let e = if (code == 0)
-                       then ExitSuccess
-                       else (ExitFailure (fromIntegral code))
-                return (ClosedHandle e, e)
-        when delegating_ctlc $
-          endDelegateControlC e
-        return e
-
-
--- ----------------------------------------------------------------------------
--- getProcessExitCode
-
-{- |
-This is a non-blocking version of 'waitForProcess'.  If the process is
-still running, 'Nothing' is returned.  If the process has exited, then
-@'Just' e@ is returned where @e@ is the exit code of the process.
-
-On Unix systems, see 'waitForProcess' for the meaning of exit codes
-when the process died as the result of a signal.
--}
-
-getProcessExitCode :: ProcessHandle -> IO (Maybe ExitCode)
-getProcessExitCode ph@(ProcessHandle _ delegating_ctlc) = do
-  (m_e, was_open) <- modifyProcessHandle ph $ \p_ ->
-    case p_ of
-      ClosedHandle e -> return (p_, (Just e, False))
-      OpenHandle h ->
-        alloca $ \pExitCode -> do
-            res <- throwErrnoIfMinus1Retry "getProcessExitCode" $
-                        c_getProcessExitCode h pExitCode
-            code <- peek pExitCode
-            if res == 0
-              then return (p_, (Nothing, False))
-              else do
-                   closePHANDLE h
-                   let e  | code == 0 = ExitSuccess
-                          | otherwise = ExitFailure (fromIntegral code)
-                   return (ClosedHandle e, (Just e, True))
-  case m_e of
-    Just e | was_open && delegating_ctlc -> endDelegateControlC e
-    _                                    -> return ()
-  return m_e
-
-
--- ----------------------------------------------------------------------------
--- terminateProcess
-
--- | Attempts to terminate the specified process.  This function should
--- not be used under normal circumstances - no guarantees are given regarding
--- how cleanly the process is terminated.  To check whether the process
--- has indeed terminated, use 'getProcessExitCode'.
---
--- On Unix systems, 'terminateProcess' sends the process the SIGTERM signal.
--- On Windows systems, the Win32 @TerminateProcess@ function is called, passing
--- an exit code of 1.
---
--- Note: on Windows, if the process was a shell command created by
--- 'createProcess' with 'shell', or created by 'runCommand' or
--- 'runInteractiveCommand', then 'terminateProcess' will only
--- terminate the shell, not the command itself.  On Unix systems, both
--- processes are in a process group and will be terminated together.
-
-terminateProcess :: ProcessHandle -> IO ()
-terminateProcess ph = do
-  withProcessHandle ph $ \p_ ->
-    case p_ of
-      ClosedHandle _ -> return ()
-      OpenHandle h -> do
-        throwErrnoIfMinus1Retry_ "terminateProcess" $ c_terminateProcess h
-        return ()
-        -- does not close the handle, we might want to try terminating it
-        -- again, or get its exit code.
-
-
--- ----------------------------------------------------------------------------
--- interruptProcessGroupOf
-
--- | Sends an interrupt signal to the process group of the given process.
---
--- On Unix systems, it sends the group the SIGINT signal.
---
--- On Windows systems, it generates a CTRL_BREAK_EVENT and will only work for
--- processes created using 'createProcess' and setting the 'create_group' flag
-
-interruptProcessGroupOf
-    :: ProcessHandle    -- ^ A process in the process group
-    -> IO ()
-interruptProcessGroupOf ph = do
-    withProcessHandle ph $ \p_ -> do
-        case p_ of
-            ClosedHandle _ -> return ()
-            OpenHandle h -> do
-#if mingw32_HOST_OS
-                pid <- getProcessId h
-                generateConsoleCtrlEvent cTRL_BREAK_EVENT pid
--- We can't use an #elif here, because MIN_VERSION_unix isn't defined
--- on Windows, so on Windows cpp fails:
--- error: missing binary operator before token "("
-#else
-                pgid <- getProcessGroupIDOf h
-                signalProcessGroup sigINT pgid
-#endif
-                return ()
-
-
--- ----------------------------------------------------------------------------
--- Interface to C bits
-
-foreign import ccall unsafe "terminateProcess"
-  c_terminateProcess
-        :: PHANDLE
-        -> IO CInt
-
-foreign import ccall unsafe "getProcessExitCode"
-  c_getProcessExitCode
-        :: PHANDLE
-        -> Ptr CInt
-        -> IO CInt
-
-foreign import ccall interruptible "waitForProcess" -- NB. safe - can block
-  c_waitForProcess
-        :: PHANDLE
-        -> Ptr CInt
-        -> IO CInt
-
-
--- ----------------------------------------------------------------------------
--- Old deprecated variants
--- ----------------------------------------------------------------------------
-
--- TODO: We're not going to mark these functions as DEPRECATED immediately in
--- process-1.2.0.0. That's because some of their replacements have not been
--- around for all that long. But they should eventually be marked with a
--- suitable DEPRECATED pragma after a release or two.
-
-
--- ----------------------------------------------------------------------------
--- runCommand
-
---TODO: in a later release {-# DEPRECATED runCommand "Use 'spawnCommand' instead" #-}
-
-{- | Runs a command using the shell.
- -}
-runCommand
-  :: String
-  -> IO ProcessHandle
-
-runCommand string = do
-  (_,_,_,ph) <- createProcess_ "runCommand" (shell string)
-  return ph
-
-
--- ----------------------------------------------------------------------------
--- runProcess
-
---TODO: in a later release {-# DEPRECATED runProcess "Use 'spawnProcess' or 'createProcess' instead" #-}
-
-{- | Runs a raw command, optionally specifying 'Handle's from which to
-     take the @stdin@, @stdout@ and @stderr@ channels for the new
-     process (otherwise these handles are inherited from the current
-     process).
-
-     Any 'Handle's passed to 'runProcess' are placed immediately in the
-     closed state.
-
-     Note: consider using the more general 'createProcess' instead of
-     'runProcess'.
--}
-runProcess
-  :: FilePath                   -- ^ Filename of the executable (see 'RawCommand' for details)
-  -> [String]                   -- ^ Arguments to pass to the executable
-  -> Maybe FilePath             -- ^ Optional path to the working directory
-  -> Maybe [(String,String)]    -- ^ Optional environment (otherwise inherit)
-  -> Maybe Handle               -- ^ Handle to use for @stdin@ (Nothing => use existing @stdin@)
-  -> Maybe Handle               -- ^ Handle to use for @stdout@ (Nothing => use existing @stdout@)
-  -> Maybe Handle               -- ^ Handle to use for @stderr@ (Nothing => use existing @stderr@)
-  -> IO ProcessHandle
-
-runProcess cmd args mb_cwd mb_env mb_stdin mb_stdout mb_stderr = do
-  (_,_,_,ph) <-
-      createProcess_ "runProcess"
-         (proc cmd args){ cwd = mb_cwd,
-                          env = mb_env,
-                          std_in  = mbToStd mb_stdin,
-                          std_out = mbToStd mb_stdout,
-                          std_err = mbToStd mb_stderr }
-  maybeClose mb_stdin
-  maybeClose mb_stdout
-  maybeClose mb_stderr
-  return ph
- where
-  maybeClose :: Maybe Handle -> IO ()
-  maybeClose (Just  hdl)
-    | hdl /= stdin && hdl /= stdout && hdl /= stderr = hClose hdl
-  maybeClose _ = return ()
-
-  mbToStd :: Maybe Handle -> StdStream
-  mbToStd Nothing    = Inherit
-  mbToStd (Just hdl) = UseHandle hdl
-
-
--- ----------------------------------------------------------------------------
--- runInteractiveCommand
-
---TODO: in a later release {-# DEPRECATED runInteractiveCommand "Use 'createProcess' instead" #-}
-
-{- | Runs a command using the shell, and returns 'Handle's that may
-     be used to communicate with the process via its @stdin@, @stdout@,
-     and @stderr@ respectively. The 'Handle's are initially in binary
-     mode; if you need them to be in text mode then use 'hSetBinaryMode'.
--}
-runInteractiveCommand
-  :: String
-  -> IO (Handle,Handle,Handle,ProcessHandle)
-
-runInteractiveCommand string =
-  runInteractiveProcess1 "runInteractiveCommand" (shell string)
-
-
--- ----------------------------------------------------------------------------
--- runInteractiveProcess
-
---TODO: in a later release {-# DEPRECATED runInteractiveCommand "Use 'createProcess' instead" #-}
-
-{- | Runs a raw command, and returns 'Handle's that may be used to communicate
-     with the process via its @stdin@, @stdout@ and @stderr@ respectively.
-
-    For example, to start a process and feed a string to its stdin:
-
->   (inp,out,err,pid) <- runInteractiveProcess "..."
->   forkIO (hPutStr inp str)
-
-    The 'Handle's are initially in binary mode; if you need them to be
-    in text mode then use 'hSetBinaryMode'.
--}
-runInteractiveProcess
-  :: FilePath                   -- ^ Filename of the executable (see 'RawCommand' for details)
-  -> [String]                   -- ^ Arguments to pass to the executable
-  -> Maybe FilePath             -- ^ Optional path to the working directory
-  -> Maybe [(String,String)]    -- ^ Optional environment (otherwise inherit)
-  -> IO (Handle,Handle,Handle,ProcessHandle)
-
-runInteractiveProcess cmd args mb_cwd mb_env = do
-  runInteractiveProcess1 "runInteractiveProcess"
-        (proc cmd args){ cwd = mb_cwd, env = mb_env }
-
-runInteractiveProcess1
-  :: String
-  -> CreateProcess
-  -> IO (Handle,Handle,Handle,ProcessHandle)
-runInteractiveProcess1 fun cmd = do
-  (mb_in, mb_out, mb_err, p) <-
-      createProcess_ fun
-           cmd{ std_in  = CreatePipe,
-                std_out = CreatePipe,
-                std_err = CreatePipe }
-  return (fromJust mb_in, fromJust mb_out, fromJust mb_err, p)
-
-
--- ---------------------------------------------------------------------------
--- system & rawSystem
-
---TODO: in a later release {-# DEPRECATED system "Use 'callCommand' (or 'spawnCommand' and 'waitForProcess') instead" #-}
-
-{-|
-Computation @system cmd@ returns the exit code produced when the
-operating system runs the shell command @cmd@.
-
-This computation may fail with one of the following
-'System.IO.Error.IOErrorType' exceptions:
-
-[@PermissionDenied@]
-The process has insufficient privileges to perform the operation.
-
-[@ResourceExhausted@]
-Insufficient resources are available to perform the operation.
-
-[@UnsupportedOperation@]
-The implementation does not support system calls.
-
-On Windows, 'system' passes the command to the Windows command
-interpreter (@CMD.EXE@ or @COMMAND.COM@), hence Unixy shell tricks
-will not work.
-
-On Unix systems, see 'waitForProcess' for the meaning of exit codes
-when the process died as the result of a signal.
--}
-#ifdef __GLASGOW_HASKELL__
-system :: String -> IO ExitCode
-system "" = ioException (ioeSetErrorString (mkIOError InvalidArgument "system" Nothing Nothing) "null command")
-system str = do
-  (_,_,_,p) <- createProcess_ "system" (shell str) { delegate_ctlc = True }
-  waitForProcess p
-#endif  /* __GLASGOW_HASKELL__ */
-
-
---TODO: in a later release {-# DEPRECATED rawSystem "Use 'callProcess' (or 'spawnProcess' and 'waitForProcess') instead" #-}
-
-{-|
-The computation @'rawSystem' /cmd/ /args/@ runs the operating system command
-@/cmd/@ in such a way that it receives as arguments the @/args/@ strings
-exactly as given, with no funny escaping or shell meta-syntax expansion.
-It will therefore behave more portably between operating systems than 'system'.
-
-The return codes and possible failures are the same as for 'system'.
--}
-rawSystem :: String -> [String] -> IO ExitCode
-#ifdef __GLASGOW_HASKELL__
-rawSystem cmd args = do
-  (_,_,_,p) <- createProcess_ "rawSystem" (proc cmd args) { delegate_ctlc = True }
-  waitForProcess p
-#elif !mingw32_HOST_OS
--- crude fallback implementation: could do much better than this under Unix
-rawSystem cmd args = system (showCommandForUser cmd args)
-#else
-rawSystem cmd args = system (showCommandForUser cmd args)
-#endif
-
--- ---------------------------------------------------------------------------
--- createPipe
-
--- | Create a pipe for interprocess communication and return a
--- @(readEnd, writeEnd)@ `Handle` pair.
---
--- @since 1.2.1.0
-createPipe :: IO (Handle, Handle)
-#if !mingw32_HOST_OS
-createPipe = do
-    (readfd, writefd) <- Posix.createPipe
-    readh <- Posix.fdToHandle readfd
-    writeh <- Posix.fdToHandle writefd
-    return (readh, writeh)
-#else
-createPipe = do
-    (readfd, writefd) <- allocaArray 2 $ \ pfds -> do
-        throwErrnoIfMinus1_ "_pipe" $ c__pipe pfds 2 (#const _O_BINARY)
-        readfd <- peek pfds
-        writefd <- peekElemOff pfds 1
-        return (readfd, writefd)
-    (do readh <- fdToHandle readfd
-        writeh <- fdToHandle writefd
-        return (readh, writeh)) `onException` (close readfd >> close writefd)
-
-close :: CInt -> IO ()
-close = throwErrnoIfMinus1_ "_close" . c__close
-
-foreign import ccall "io.h _pipe" c__pipe ::
-    Ptr CInt -> CUInt -> CInt -> IO CInt
-
-foreign import ccall "io.h _close" c__close ::
-    CInt -> IO CInt
-#endif
diff --git a/System/Process/Common.hs b/System/Process/Common.hs
new file mode 100644
--- /dev/null
+++ b/System/Process/Common.hs
@@ -0,0 +1,333 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE RecordWildCards #-}
+module System.Process.Common
+    ( CreateProcess (..)
+    , CmdSpec (..)
+    , StdStream (..)
+    , ProcessHandle(..)
+    , ProcessHandle__(..)
+    , ProcRetHandles (..)
+    , withFilePathException
+    , PHANDLE
+    , GroupID
+    , UserID
+    , modifyProcessHandle
+    , withProcessHandle
+    , fd_stdin
+    , fd_stdout
+    , fd_stderr
+    , mbFd
+    , mbPipe
+    , pfdToHandle
+    , rawFdToHandle
+
+-- Avoid a warning on Windows
+#if defined(mingw32_HOST_OS)
+    , CGid (..)
+#else
+    , CGid
+#endif
+
+#if defined(mingw32_HOST_OS)
+    , HANDLE
+-- WINIO is only available on GHC 9.0 and up.
+#  if defined(__IO_MANAGER_WINIO__)
+    , mbHANDLE
+    , mbPipeHANDLE
+    , rawHANDLEToHandle
+#  endif
+#endif
+    ) where
+
+import Control.Concurrent
+import Control.Exception
+import Data.String ( IsString(..) )
+import Foreign.Ptr
+import Foreign.Storable ( Storable(peek) )
+
+import System.Posix.Internals
+import GHC.IO.Exception
+import GHC.IO.Encoding
+import qualified GHC.IO.FD as FD
+import GHC.IO.Device
+#if defined(__IO_MANAGER_WINIO__)
+import GHC.IO.Handle.Windows
+import GHC.IO.Windows.Handle (fromHANDLE, Io(), NativeHandle())
+#endif
+import GHC.IO.Handle.FD
+import GHC.IO.Handle.Internals
+import GHC.IO.Handle.Types hiding (ClosedHandle)
+import System.IO.Error
+import Data.Typeable
+import System.IO (IOMode)
+
+#if defined(javascript_HOST_ARCH)
+import GHC.JS.Prim (JSVal)
+#endif
+
+-- We do a minimal amount of CPP here to provide uniform data types across
+-- Windows and POSIX.
+#if defined(mingw32_HOST_OS)
+import Data.Word (Word32)
+import System.Win32.DebugApi (PHANDLE)
+#if defined(__IO_MANAGER_WINIO__)
+import System.Win32.Types (HANDLE)
+#endif
+#else
+import System.Posix.Types
+#endif
+
+#if defined(javascript_HOST_ARCH)
+type PHANDLE = JSVal
+#elif defined(mingw32_HOST_OS)
+-- Define some missing types for Windows compatibility. Note that these values
+-- will never actually be used, as the setuid/setgid system calls are not
+-- applicable on Windows. No value of this type will ever exist.
+newtype CGid = CGid Word32
+  deriving (Show, Eq)
+type GroupID = CGid
+type UserID = CGid
+#else
+type PHANDLE = CPid
+#endif
+data CreateProcess = CreateProcess{
+  cmdspec      :: CmdSpec,                 -- ^ Executable & arguments, or shell command.  If 'cwd' is 'Nothing', relative paths are resolved with respect to the current working directory.  If 'cwd' is provided, it is implementation-dependent whether relative paths are resolved with respect to 'cwd' or the current working directory, so absolute paths should be used to ensure portability.
+  cwd          :: Maybe FilePath,          -- ^ Optional path to the working directory for the new process
+  env          :: Maybe [(String,String)], -- ^ Optional environment (otherwise inherit from the current process)
+  std_in       :: StdStream,               -- ^ How to determine stdin
+  std_out      :: StdStream,               -- ^ How to determine stdout
+  std_err      :: StdStream,               -- ^ How to determine stderr
+  -- XXX verify what happens with fds in nodejs child processes
+  close_fds    :: Bool,                    -- ^ Close all file descriptors except stdin, stdout and stderr in the new process (on Windows, only works if std_in, std_out, and std_err are all Inherit). This implementation will call close on every fd from 3 to the maximum of open files, which can be slow for high maximum of open files.
+  create_group :: Bool,                    -- ^ Create a new process group. On JavaScript this also creates a new session.
+  delegate_ctlc:: Bool,                    -- ^ Delegate control-C handling. Use this for interactive console processes to let them handle control-C themselves (see below for details).
+                                           --
+                                           --   @since 1.2.0.0
+  detach_console :: Bool,                  -- ^ Use the windows DETACHED_PROCESS flag when creating the process; does nothing on other platforms.
+                                           --
+                                           --   @since 1.3.0.0
+  create_new_console :: Bool,              -- ^ Use the windows CREATE_NEW_CONSOLE flag when creating the process; does nothing on other platforms.
+                                           --
+                                           --   Default: @False@
+                                           --
+                                           --   @since 1.3.0.0
+  new_session :: Bool,                     -- ^ Use posix setsid to start the new process in a new session; starts process in a new session on JavaScript; does nothing on other platforms.
+                                           --
+                                           --   @since 1.3.0.0
+  child_group :: Maybe GroupID,            -- ^ Use posix setgid to set child process's group id; works for JavaScript when system running nodejs is posix. does nothing on other platforms.
+                                           --
+                                           --   Default: @Nothing@
+                                           --
+                                           --   @since 1.4.0.0
+  child_user :: Maybe UserID,              -- ^ Use posix setuid to set child process's user id; works for JavaScript when system running nodejs is posix. does nothing on other platforms.
+                                           --
+                                           --   Default: @Nothing@
+                                           --
+                                           --   @since 1.4.0.0
+  use_process_jobs :: Bool                 -- ^ On Windows systems this flag indicates that we should wait for the entire process tree
+                                           --   to finish before unblocking. On POSIX systems this flag is ignored. See $exec-on-windows for details.
+                                           --
+                                           --   Default: @False@
+                                           --
+                                           --   @since 1.5.0.0
+ } deriving (Show, Eq)
+
+-- | contains the handles returned by a call to createProcess_Internal
+data ProcRetHandles
+  = ProcRetHandles { hStdInput      :: Maybe Handle
+                   , hStdOutput     :: Maybe Handle
+                   , hStdError      :: Maybe Handle
+                   , procHandle     :: ProcessHandle
+                   }
+
+data CmdSpec
+  = ShellCommand String
+      -- ^ A command line to execute using the shell
+  | RawCommand FilePath [String]
+      -- ^ The name of an executable with a list of arguments
+      --
+      -- The 'FilePath' argument names the executable, and is interpreted
+      -- according to the platform's standard policy for searching for
+      -- executables. Specifically:
+      --
+      -- * on Unix systems the
+      --   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/execvp.html execvp(3)>
+      --   semantics is used, where if the executable filename does not
+      --   contain a slash (@/@) then the @PATH@ environment variable is
+      --   searched for the executable.
+      --
+      -- * on Windows systems the Win32 @CreateProcess@ semantics is used.
+      --   Briefly: if the filename does not contain a path, then the
+      --   directory containing the parent executable is searched, followed
+      --   by the current directory, then some standard locations, and
+      --   finally the current @PATH@.  An @.exe@ extension is added if the
+      --   filename does not already have an extension.  For full details
+      --   see the
+      --   <http://msdn.microsoft.com/en-us/library/windows/desktop/aa365527%28v=vs.85%29.aspx documentation>
+      --   for the Windows @SearchPath@ API.
+      --
+      --   Windows does not have a mechanism for passing multiple arguments.
+      --   When using @RawCommand@ on Windows, the command line is serialised
+      --   into a string, with arguments quoted separately.  Command line
+      --   parsing is up individual programs, so the default behaviour may
+      --   not work for some programs.  If you are not getting the desired
+      --   results, construct the command line yourself and use 'ShellCommand'.
+      --
+  deriving (Show, Eq)
+
+
+-- | construct a `ShellCommand` from a string literal
+--
+-- @since 1.2.1.0
+instance IsString CmdSpec where
+  fromString = ShellCommand
+
+data StdStream
+  = Inherit                  -- ^ Inherit Handle from parent
+  | UseHandle Handle         -- ^ Use the supplied Handle
+  | CreatePipe               -- ^ Create a new pipe.  The returned
+                             -- @Handle@ will use the default encoding
+                             -- and newline translation mode (just
+                             -- like @Handle@s created by @openFile@).
+  | NoStream                 -- ^ Close the stream's file descriptor without
+                             -- passing a Handle. On POSIX systems this may
+                             -- lead to strange behavior in the child process
+                             -- because attempting to read or write after the
+                             -- file has been closed throws an error. This
+                             -- should only be used with child processes that
+                             -- don't use the file descriptor at all. If you
+                             -- wish to ignore the child process's output you
+                             -- should either create a pipe and drain it
+                             -- manually or pass a @Handle@ that writes to
+                             -- @\/dev\/null@.
+  deriving (Eq, Show)
+
+-- ----------------------------------------------------------------------------
+-- ProcessHandle type
+
+data ProcessHandle__ = OpenHandle { phdlProcessHandle :: PHANDLE }
+                     -- | 'OpenExtHandle' is only applicable for
+                     -- Windows platform. It represents [Job
+                     -- Objects](https://learn.microsoft.com/en-us/windows/win32/procthread/job-objects).
+                     | OpenExtHandle { phdlProcessHandle :: PHANDLE
+                                     -- ^ the process
+                                     , phdlJobHandle     :: PHANDLE
+                                     -- ^ the job containing the process and
+                                     -- its subprocesses
+                                     }
+                     | ClosedHandle ExitCode
+
+{- | A handle to a process, which can be used to wait for termination
+     of the process using 'System.Process.waitForProcess'.
+
+     None of the process-creation functions in this library wait for
+     termination: they all return a 'ProcessHandle' which may be used
+     to wait for the process later.
+
+     On Windows a second wait method can be used to block for event
+     completion. This requires two handles. A process job handle and
+     a events handle to monitor.
+-}
+data ProcessHandle
+  = ProcessHandle { phandle          :: !(MVar ProcessHandle__)
+                  , mb_delegate_ctlc :: !Bool
+                  , waitpidLock      :: !(MVar ())
+                  }
+
+withFilePathException :: FilePath -> IO a -> IO a
+withFilePathException fpath act = handle mapEx act
+  where
+    mapEx ex = ioError (ioeSetFileName ex fpath)
+
+modifyProcessHandle
+        :: ProcessHandle
+        -> (ProcessHandle__ -> IO (ProcessHandle__, a))
+        -> IO a
+modifyProcessHandle (ProcessHandle m _ _) io = modifyMVar m io
+
+withProcessHandle
+        :: ProcessHandle
+        -> (ProcessHandle__ -> IO a)
+        -> IO a
+withProcessHandle (ProcessHandle m _ _) io = withMVar m io
+
+fd_stdin, fd_stdout, fd_stderr :: FD
+fd_stdin  = 0
+fd_stdout = 1
+fd_stderr = 2
+
+mbFd :: String -> FD -> StdStream -> IO FD
+mbFd _   _std CreatePipe      = return (-1)
+mbFd _fun std Inherit         = return std
+mbFd _fn _std NoStream        = return (-2)
+mbFd fun _std (UseHandle hdl) =
+  withHandle fun hdl $ \Handle__{haDevice=dev,..} -> do
+    case cast dev of
+      Just fd -> do
+#if !defined(javascript_HOST_ARCH)
+         -- clear the O_NONBLOCK flag on this FD, if it is set, since
+         -- we're exposing it externally (see #3316)
+         fd' <- FD.setNonBlockingMode fd False
+#else
+         -- on the JavaScript platform we cannot change the FD flags
+         fd' <- pure fd
+#endif
+         return (Handle__{haDevice=fd',..}, FD.fdFD fd')
+      Nothing ->
+          ioError (mkIOError illegalOperationErrorType
+                      "createProcess" (Just hdl) Nothing
+                   `ioeSetErrorString` "handle is not a file descriptor")
+
+mbPipe :: StdStream -> Ptr FD -> IOMode -> IO (Maybe Handle)
+mbPipe CreatePipe pfd  mode = fmap Just (pfdToHandle pfd mode)
+mbPipe _std      _pfd _mode = return Nothing
+
+pfdToHandle :: Ptr FD -> IOMode -> IO Handle
+pfdToHandle pfd mode =
+  ( \ fd -> rawFdToHandle fd mode ) =<< peek pfd
+
+rawFdToHandle :: FD -> IOMode -> IO Handle
+rawFdToHandle fd mode = do
+  let filepath = "fd:" ++ show fd
+  (fD,fd_type) <- FD.mkFD (fromIntegral fd) mode
+                       (Just (Stream,0,0)) -- avoid calling fstat()
+                       False {-is_socket-}
+                       False {-non-blocking-}
+  fD' <- FD.setNonBlockingMode fD True -- see #3316
+#if __GLASGOW_HASKELL__ >= 704
+  enc <- getLocaleEncoding
+#else
+  let enc = localeEncoding
+#endif
+  mkHandleFromFD fD' fd_type filepath mode False {-is_socket-} (Just enc)
+
+
+#if defined(mingw32_HOST_OS) && !defined(__IO_MANAGER_WINIO__)
+type HANDLE = Ptr ()
+#endif
+
+#if defined(__IO_MANAGER_WINIO__)
+-- It is not completely safe to pass the values -1 and -2 as HANDLE as it's an
+-- unsigned type. -1 additionally is also the value for INVALID_HANDLE.  However
+-- it should be safe in this case since an invalid handle would be an error here
+-- anyway and the chances of us getting a handle with a value of -2 is
+-- astronomical. However, sometime in the future process should really use a
+-- proper structure here.
+mbHANDLE :: HANDLE -> StdStream -> IO HANDLE
+mbHANDLE _std CreatePipe      = return $ intPtrToPtr (-1)
+mbHANDLE  std Inherit         = return std
+mbHANDLE _std NoStream        = return $ intPtrToPtr (-2)
+mbHANDLE _std (UseHandle hdl) = handleToHANDLE hdl
+
+mbPipeHANDLE :: StdStream -> Ptr HANDLE -> IOMode -> IO (Maybe Handle)
+mbPipeHANDLE CreatePipe pfd mode =
+  Just <$> ( ( \ hANDLE -> rawHANDLEToHandle hANDLE mode ) =<< peek pfd )
+mbPipeHANDLE _std      _pfd _mode = return Nothing
+
+rawHANDLEToHandle :: HANDLE -> IOMode-> IO Handle
+rawHANDLEToHandle raw_handle mode  = do
+  let hwnd  = fromHANDLE raw_handle :: Io NativeHandle
+      ident = "hwnd:" ++ show raw_handle
+  enc <- getLocaleEncoding
+  mkHandleFromHANDLE hwnd Stream ident mode (Just enc)
+#endif
diff --git a/System/Process/CommunicationHandle.hs b/System/Process/CommunicationHandle.hs
new file mode 100644
--- /dev/null
+++ b/System/Process/CommunicationHandle.hs
@@ -0,0 +1,155 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE RankNTypes #-}
+
+module System.Process.CommunicationHandle
+  ( -- * 'CommunicationHandle': a 'Handle' that can be serialised,
+    -- enabling inter-process communication.
+    CommunicationHandle
+      -- NB: opaque, as the representation depends on the operating system
+  , openCommunicationHandleRead
+  , openCommunicationHandleWrite
+  , closeCommunicationHandle
+    -- * Creating 'CommunicationHandle's to communicate with
+    -- a child process
+  , createWeReadTheyWritePipe
+  , createTheyReadWeWritePipe
+   -- * High-level API
+  , readCreateProcessWithExitCodeCommunicationHandle
+  )
+ where
+
+import GHC.IO.Handle (Handle)
+
+import System.Process.CommunicationHandle.Internal
+import System.Process.Internals
+  ( CreateProcess(..), ignoreSigPipe, withForkWait )
+import System.Process
+  ( withCreateProcess, waitForProcess )
+
+import GHC.IO (evaluate)
+import GHC.IO.Handle (hClose)
+import System.Exit (ExitCode)
+
+import Control.DeepSeq (NFData, rnf)
+
+--------------------------------------------------------------------------------
+-- Communication handles.
+
+-- | Turn the 'CommunicationHandle' into a 'Handle' that can be read from
+-- in the current process.
+--
+-- The returned 'Handle' does not have any finalizers attached to it;
+-- use 'hClose' to close it.
+--
+-- @since 1.6.20.0
+openCommunicationHandleRead :: CommunicationHandle -> IO Handle
+openCommunicationHandleRead = useCommunicationHandle True
+
+-- | Turn the 'CommunicationHandle' into a 'Handle' that can be written to
+-- in the current process.
+--
+-- The returned 'Handle' does not have any finalizers attached to it;
+-- use 'hClose' to close it.
+--
+-- @since 1.6.20.0
+openCommunicationHandleWrite :: CommunicationHandle -> IO Handle
+openCommunicationHandleWrite = useCommunicationHandle False
+
+--------------------------------------------------------------------------------
+-- Creating pipes.
+
+-- | Create a pipe @(weRead,theyWrite)@ that the current process can read from,
+-- and whose write end can be passed to a child process in order to receive data from it.
+--
+-- The returned 'Handle' does not have any finalizers attached to it;
+-- use 'hClose' to close it.
+--
+-- See 'CommunicationHandle'.
+--
+-- @since 1.6.20.0
+createWeReadTheyWritePipe
+  :: IO (Handle, CommunicationHandle)
+createWeReadTheyWritePipe =
+  createCommunicationPipe id False
+    -- safe choice: passAsyncHandleToChild = False, in case the child cannot
+    -- deal with async I/O (see e.g. https://gitlab.haskell.org/ghc/ghc/-/issues/21610#note_431632)
+    -- expert users can invoke createCommunicationPipe from
+    -- System.Process.CommunicationHandle.Internals if they are sure that the
+    -- child process they will communicate with supports async I/O on Windows
+
+-- | Create a pipe @(theyRead,weWrite)@ that the current process can write to,
+-- and whose read end can be passed to a child process in order to send data to it.
+--
+-- The returned 'Handle' does not have any finalizers attached to it;
+-- use 'hClose' to close it.
+--
+-- See 'CommunicationHandle'.
+--
+-- @since 1.6.20.0
+createTheyReadWeWritePipe
+  :: IO (CommunicationHandle, Handle)
+createTheyReadWeWritePipe =
+  sw <$> createCommunicationPipe sw False
+    -- safe choice: passAsyncHandleToChild = False, in case the child cannot
+    -- deal with async I/O (see e.g. https://gitlab.haskell.org/ghc/ghc/-/issues/21610#note_431632)
+    -- expert users can invoke createCommunicationPipe from
+    -- System.Process.CommunicationHandle.Internals if they are sure that the
+    -- child process they will communicate with supports async I/O on Windows
+  where
+    sw (a,b) = (b,a)
+
+--------------------------------------------------------------------------------
+
+-- | A version of 'readCreateProcessWithExitCode' that communicates with the
+-- child process through a pair of 'CommunicationHandle's.
+--
+-- Example usage:
+--
+-- > readCreateProcessWithExitCodeCommunicationHandle
+-- >   (\(chTheyRead, chTheyWrite) -> proc "child-exe" [show chTheyRead, show chTheyWrite])
+-- >   (\ hWeRead -> hGetContents hWeRead)
+-- >   (\ hWeWrite -> hPut hWeWrite "xyz")
+--
+-- where @child-exe@ is a separate executable that is implemented as:
+--
+-- > main = do
+-- >   [chRead, chWrite] <- getArgs
+-- >   hRead  <- openCommunicationHandleRead  $ read chRead
+-- >   hWrite <- openCommunicationHandleWrite $ read chWrite
+-- >   input <- hGetContents hRead
+-- >   hPut hWrite $ someFn input
+-- >   hClose hWrite
+--
+-- @since 1.6.20.0
+readCreateProcessWithExitCodeCommunicationHandle
+  :: NFData a
+  => ((CommunicationHandle, CommunicationHandle) -> CreateProcess)
+    -- ^ Process to spawn, given a @(read, write)@ pair of
+    -- 'CommunicationHandle's that are inherited by the spawned process
+  -> (Handle -> IO a)
+    -- ^ read action
+  -> (Handle -> IO ())
+    -- ^ write action
+  -> IO (ExitCode, a)
+readCreateProcessWithExitCodeCommunicationHandle mkProg readAction writeAction = do
+  (chTheyRead, hWeWrite   ) <- createTheyReadWeWritePipe
+  (hWeRead   , chTheyWrite) <- createWeReadTheyWritePipe
+  let cp = mkProg (chTheyRead, chTheyWrite)
+  -- The following implementation parallels 'readCreateProcess'
+  withCreateProcess cp $ \ _ _ _ ph -> do
+
+    -- Close the parent's references to the 'CommunicationHandle's after they
+    -- have been inherited by the child (we don't want to keep pipe ends open).
+    closeCommunicationHandle chTheyWrite
+    closeCommunicationHandle chTheyRead
+
+    -- Fork off a thread that waits on the output.
+    output <- readAction hWeRead
+    withForkWait (evaluate $ rnf output) $ \ waitOut -> do
+      ignoreSigPipe $ writeAction hWeWrite
+      ignoreSigPipe $ hClose hWeWrite
+      waitOut
+      hClose hWeRead
+
+    ex <- waitForProcess ph
+    return (ex, output)
diff --git a/System/Process/CommunicationHandle/Internal.hsc b/System/Process/CommunicationHandle/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/System/Process/CommunicationHandle/Internal.hsc
@@ -0,0 +1,311 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE RankNTypes #-}
+
+module System.Process.CommunicationHandle.Internal
+  ( -- * 'CommunicationHandle': a 'Handle' that can be serialised,
+    -- enabling inter-process communication.
+    CommunicationHandle(..)
+  , closeCommunicationHandle
+    -- ** Internal functions
+  , useCommunicationHandle
+  , createCommunicationPipe
+  )
+ where
+
+import Control.Arrow ( first )
+import GHC.IO.Handle (Handle, hClose)
+#if defined(mingw32_HOST_OS)
+import Foreign.C (CInt(..), throwErrnoIf_)
+import Foreign.Marshal (alloca)
+import Foreign.Ptr (ptrToWordPtr, wordPtrToPtr)
+import Foreign.Storable (Storable(peek))
+import GHC.IO.Handle.FD (fdToHandle)
+import GHC.IO.IOMode (IOMode(ReadMode, WriteMode))
+import System.Process.Windows (HANDLE, mkNamedPipe)
+##  if defined(__IO_MANAGER_WINIO__)
+import Control.Exception (catch, throwIO)
+import GHC.IO (onException)
+import GHC.IO.Device as IODevice (close, devType)
+import GHC.IO.Encoding (getLocaleEncoding)
+import GHC.IO.Exception (IOException(..), IOErrorType(InvalidArgument))
+import GHC.IO.IOMode (IOMode(ReadWriteMode))
+import GHC.IO.Handle.Windows (mkHandleFromHANDLE)
+import GHC.IO.SubSystem ((<!>))
+import GHC.IO.Windows.Handle (Io, NativeHandle, fromHANDLE)
+import GHC.Event.Windows (associateHandle')
+import System.Process.Common (rawHANDLEToHandle)
+##  else
+import System.Process.Common (rawFdToHandle)
+##  endif
+
+#include <fcntl.h>     /* for _O_BINARY */
+
+#else
+import GHC.IO.FD
+  ( mkFD, setNonBlockingMode )
+import GHC.IO.Handle
+  ( noNewlineTranslation )
+#if MIN_VERSION_base(4,16,0)
+import GHC.IO.Handle.Internals
+  ( mkFileHandleNoFinalizer )
+#else
+import GHC.IO.IOMode
+  ( IOMode(..) )
+import GHC.IO.Handle.Types
+  ( HandleType(..) )
+import GHC.IO.Handle.Internals
+  ( mkHandle )
+#endif
+import System.Posix
+  ( Fd(..)
+  , FdOption(..), setFdOption
+  )
+import System.Posix.Internals
+  ( fdGetMode )
+import System.Process.Internals
+  ( createPipeFd )
+#endif
+
+--------------------------------------------------------------------------------
+-- Communication handles.
+
+-- | A 'CommunicationHandle' is an abstraction over operating-system specific
+-- internal representation of a 'Handle', which can be communicated through a
+-- command-line interface.
+--
+-- In a typical use case, the parent process creates a pipe, using e.g.
+-- 'createWeReadTheyWritePipe' or 'createTheyReadWeWritePipe'.
+--
+--  - One end of the pipe is a 'Handle', which can be read from/written to by
+--    the parent process.
+--  - The other end is a 'CommunicationHandle', which can be inherited by a
+--    child process. A reference to the handle can be serialised (using
+--    the 'Show' instance), and passed to the child process.
+--    It is recommended to close the parent's reference to the 'CommunicationHandle'
+--    using 'closeCommunicationHandle' after it has been inherited by the child
+--    process.
+--  - The child process can deserialise the 'CommunicationHandle' (using
+--    the 'Read' instance), and then use 'openCommunicationHandleWrite' or
+--    'openCommunicationHandleRead' in order to retrieve a 'Handle' which it
+--    can write to/read from.
+--
+-- 'readCreateProcessWithExitCodeCommunicationHandle' provides a high-level API
+-- to this functionality. See there for example code.
+--
+-- @since 1.6.20.0
+newtype CommunicationHandle =
+  CommunicationHandle
+##if defined(mingw32_HOST_OS)
+    HANDLE
+##else
+    Fd
+##endif
+  deriving ( Eq, Ord )
+
+#if defined(mingw32_HOST_OS)
+type Fd = CInt
+#endif
+
+-- @since 1.6.20.0
+instance Show CommunicationHandle where
+  showsPrec p (CommunicationHandle h) =
+    showsPrec p
+##if defined(mingw32_HOST_OS)
+      $ ptrToWordPtr
+##endif
+      h
+
+-- @since 1.6.20.0
+instance Read CommunicationHandle where
+  readsPrec p str =
+    fmap
+      ( first $ CommunicationHandle
+##if defined(mingw32_HOST_OS)
+              . wordPtrToPtr
+##endif
+      ) $
+      readsPrec p str
+
+-- | Internal function used to define 'openCommunicationHandleRead' and
+-- openCommunicationHandleWrite.
+useCommunicationHandle :: Bool -> CommunicationHandle -> IO Handle
+useCommunicationHandle _wantToRead (CommunicationHandle ch) = do
+##if defined(__IO_MANAGER_WINIO__)
+  return ()
+    <!> associateHandleWithFallback _wantToRead ch
+##endif
+  getGhcHandle ch
+
+-- | Close a 'CommunicationHandle'.
+--
+-- Use this to close the 'CommunicationHandle' in the parent process after
+-- the 'CommunicationHandle' has been inherited by the child process.
+--
+-- @since 1.6.20.0
+closeCommunicationHandle :: CommunicationHandle -> IO ()
+closeCommunicationHandle (CommunicationHandle ch) =
+  hClose =<< getGhcHandle ch
+
+##if defined(__IO_MANAGER_WINIO__)
+-- Internal function used when associating a 'HANDLE' with the current process.
+--
+-- Explanation: with WinIO, a synchronous handle cannot be associated with the
+-- current process, while an asynchronous one must be associated before being usable.
+--
+-- In a child process, we don't necessarily know which kind of handle we will receive,
+-- so we try to associate it (in case it is an asynchronous handle). This might
+-- fail (if the handle is synchronous), in which case we continue in synchronous
+-- mode (without associating).
+--
+-- With the current API, inheritable handles in WinIO created with mkNamedPipe
+-- are synchronous, but it's best to be safe in case the child receives an
+-- asynchronous handle anyway.
+associateHandleWithFallback :: Bool -> HANDLE -> IO ()
+associateHandleWithFallback _wantToRead h =
+  associateHandle' h `catch` handler
+  where
+    handler :: IOError -> IO ()
+    handler ioErr@(IOError { ioe_handle = _mbErrHandle, ioe_type = errTy, ioe_errno = mbErrNo })
+      -- Catches the following error that occurs when attemping to associate
+      -- a HANDLE that does not have OVERLAPPING mode set:
+      --
+      --   associateHandleWithIOCP: invalid argument (The parameter is incorrect.)
+      | InvalidArgument <- errTy
+      , Just 22 <- mbErrNo
+      = return ()
+      | otherwise
+      = throwIO ioErr
+##endif
+
+-- | Gets a GHC Handle File description from the given OS Handle or POSIX fd.
+
+#if defined(mingw32_HOST_OS)
+getGhcHandle :: HANDLE -> IO Handle
+getGhcHandle =
+  getGhcHandlePOSIX
+##  if defined(__IO_MANAGER_WINIO__)
+    <!> getGhcHandleNative
+##  endif
+
+getGhcHandlePOSIX :: HANDLE -> IO Handle
+getGhcHandlePOSIX handle = openHANDLE handle >>= fdToHandle
+
+openHANDLE :: HANDLE -> IO Fd
+openHANDLE handle = _open_osfhandle handle (#const _O_BINARY)
+
+foreign import ccall "io.h _open_osfhandle"
+  _open_osfhandle :: HANDLE -> CInt -> IO Fd
+
+##  if defined(__IO_MANAGER_WINIO__)
+getGhcHandleNative :: HANDLE -> IO Handle
+getGhcHandleNative hwnd =
+  do mb_codec <- fmap Just getLocaleEncoding
+     let iomode = ReadWriteMode
+         native_handle = fromHANDLE hwnd :: Io NativeHandle
+     hw_type <- IODevice.devType $ native_handle
+     mkHandleFromHANDLE native_handle hw_type (show hwnd) iomode mb_codec
+       `onException` IODevice.close native_handle
+##  endif
+#else
+getGhcHandle :: Fd -> IO Handle
+getGhcHandle (Fd fdint) = do
+  iomode <- fdGetMode fdint
+  (fd0, _) <- mkFD fdint iomode Nothing False True
+  -- The following copies over 'mkHandleFromFDNoFinalizer'
+  fd <- setNonBlockingMode fd0 True
+  let fd_str = "<file descriptor: " ++ show fd ++ ">"
+#  if MIN_VERSION_base(4,16,0)
+  mkFileHandleNoFinalizer fd fd_str iomode Nothing noNewlineTranslation
+#  else
+  mkHandle fd fd_str (ioModeToHandleType iomode) True Nothing noNewlineTranslation
+    Nothing Nothing
+
+ioModeToHandleType :: IOMode -> HandleType
+ioModeToHandleType mode =
+  case mode of
+    ReadMode      -> ReadHandle
+    WriteMode     -> WriteHandle
+    ReadWriteMode -> ReadWriteHandle
+    AppendMode    -> AppendHandle
+#  endif
+#endif
+
+--------------------------------------------------------------------------------
+-- Creating pipes.
+
+-- | Internal helper function used to define 'createWeReadTheyWritePipe'
+-- and 'createTheyReadWeWritePipe' while reducing code duplication.
+--
+-- The returned 'Handle' does not have any finalizers attached to it;
+-- use 'hClose' to close it.
+createCommunicationPipe
+  :: ( forall a. (a, a) -> (a, a) )
+    -- ^ 'id' (we read, they write) or 'swap' (they read, we write)
+  -> Bool -- ^ whether to pass a handle supporting asynchronous I/O to the child process
+          -- (this flag only has an effect on Windows and when using WinIO)
+  -> IO (Handle, CommunicationHandle)
+createCommunicationPipe swapIfTheyReadWeWrite _passAsyncHandleToChild = do
+##if !defined(mingw32_HOST_OS)
+  -- NB: it's important to use 'createPipeFd' here.
+  --
+  -- Were we to instead use 'createPipe', we would create a Handle for both pipe
+  -- ends, including the end we pass to the child.
+  -- Such Handle would have a finalizer which closes the underlying file descriptor.
+  -- However, we will already close the FD after it is inherited by the child.
+  -- This could lead to the following scenario:
+  --
+  --  - the parent creates a new pipe, e.g. pipe2([7,8]),
+  --  - the parent spawns a child process, and lets FD 8 be inherited by the child,
+  --  - the parent closes FD 8,
+  --  - the parent opens FD 8 for some other purpose, e.g. for writing to a file,
+  --  - the finalizer for the Handle wrapping FD 8 runs, closing FD 8, even though
+  --    it is now in use for a completely different purpose.
+  (ourFd, theirFd) <- swapIfTheyReadWeWrite <$> createPipeFd
+  -- Don't allow the child process to inherit a parent file descriptor
+  -- (such inheritance happens by default on Unix).
+  setFdOption (Fd ourFd) CloseOnExec True
+  -- NB: we will be closing this handle manually, so don't use 'handleFromFd'
+  -- which attaches a finalizer that closes the FD. See the above comment
+  -- about 'createPipeFd'.
+  ourHandle <- getGhcHandle (Fd ourFd)
+  return (ourHandle, CommunicationHandle $ Fd theirFd)
+##else
+  trueForWinIO <-
+    return False
+##  if defined (__IO_MANAGER_WINIO__)
+      <!> return True
+##  endif
+  -- On Windows, use mkNamedPipe to create the two pipe ends.
+  alloca $ \ pfdStdInput  ->
+    alloca $ \ pfdStdOutput -> do
+      let (inheritRead, inheritWrite) = swapIfTheyReadWeWrite (False, True)
+          -- WinIO:
+          --  - make the parent pipe end overlapped,
+          --  - make the child end overlapped if requested,
+          -- Otherwise: make both pipe ends synchronous.
+          overlappedRead  = trueForWinIO && ( _passAsyncHandleToChild || not inheritRead  )
+          overlappedWrite = trueForWinIO && ( _passAsyncHandleToChild || not inheritWrite )
+      throwErrnoIf_ (==False) "mkNamedPipe" $
+        mkNamedPipe
+          pfdStdInput  inheritRead  overlappedRead
+          pfdStdOutput inheritWrite overlappedWrite
+      let ((ourPtr, ourMode), (theirPtr, _theirMode)) =
+            swapIfTheyReadWeWrite ((pfdStdInput, ReadMode), (pfdStdOutput, WriteMode))
+      ourHANDLE  <- peek ourPtr
+      theirHANDLE <- peek theirPtr
+      -- With WinIO, we need to associate any handles we are going to use in
+      -- the current process before being able to use them.
+      return ()
+##  if defined (__IO_MANAGER_WINIO__)
+        <!> associateHandle' ourHANDLE
+##  endif
+      ourHandle <-
+##  if !defined (__IO_MANAGER_WINIO__)
+        ( \ fd -> rawFdToHandle fd ourMode ) =<< openHANDLE ourHANDLE
+##  else
+        -- NB: it's OK to call the following function even when we're not
+        -- using WinIO at runtime, so we don't use <!>.
+        rawHANDLEToHandle ourHANDLE ourMode
+##  endif
+      return $ (ourHandle, CommunicationHandle theirHANDLE)
+##endif
diff --git a/System/Process/Environment/OsString.hs b/System/Process/Environment/OsString.hs
new file mode 100644
--- /dev/null
+++ b/System/Process/Environment/OsString.hs
@@ -0,0 +1,41 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE PackageImports #-}
+
+-- | Miscellaneous information about the system environment, for 'OsString'.
+--
+-- @since 1.6.26.0
+module System.Process.Environment.OsString (
+    getArgs,
+    getEnv,
+    getEnvironment,
+    ) where
+
+import Data.Coerce (coerce)
+#if MIN_VERSION_filepath(1, 5, 0)
+import "os-string" System.OsString.Internal.Types (OsString(OsString))
+#else
+import "filepath" System.OsString.Internal.Types (OsString(OsString))
+#endif
+#if defined(mingw32_HOST_OS)
+import qualified System.Win32.WindowsString.Console as Platform
+#else
+import qualified System.Posix.Env.PosixString as Platform
+#endif
+
+-- | 'System.Environment.getArgs' for 'OsString'.
+--
+-- @since 1.6.26.0
+getArgs :: IO [OsString]
+getArgs = coerce Platform.getArgs
+
+-- | 'System.Environment.getEnv' for 'OsString'.
+--
+-- @since 1.6.26.0
+getEnv :: OsString -> IO (Maybe OsString)
+getEnv = coerce Platform.getEnv
+
+-- | 'System.Environment.getEnvironment' for 'OsString'.
+--
+-- @since 1.6.26.0
+getEnvironment :: IO [(OsString, OsString)]
+getEnvironment = coerce Platform.getEnvironment
diff --git a/System/Process/Internals.hs b/System/Process/Internals.hs
--- a/System/Process/Internals.hs
+++ b/System/Process/Internals.hs
@@ -1,9 +1,7 @@
-{-# LANGUAGE CPP, RecordWildCards, BangPatterns #-}
+{-# LANGUAGE CPP #-}
 {-# OPTIONS_HADDOCK not-home #-}
-#ifdef __GLASGOW_HASKELL__
 {-# LANGUAGE Trustworthy #-}
 {-# LANGUAGE InterruptibleFFI #-}
-#endif
 
 -----------------------------------------------------------------------------
 -- |
@@ -24,219 +22,65 @@
 module System.Process.Internals (
     ProcessHandle(..), ProcessHandle__(..),
     PHANDLE, closePHANDLE, mkProcessHandle,
+#if defined(mingw32_HOST_OS)
+    CGid(..),
+#else
+    CGid,
+#endif
+    GroupID,
+    UserID,
     modifyProcessHandle, withProcessHandle,
-#ifdef __GLASGOW_HASKELL__
     CreateProcess(..),
-    CmdSpec(..), StdStream(..),
+    CmdSpec(..), StdStream(..), ProcRetHandles (..),
     createProcess_,
     runGenProcess_, --deprecated
-#endif
+    fdToHandle,
     startDelegateControlC,
     endDelegateControlC,
     stopDelegateControlC,
-#if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
+    unwrapHandles,
+#if defined(mingw32_HOST_OS)
+    terminateJob,
+    terminateJobUnsafe,
+    waitForJobCompletion,
+    timeout_Infinite,
+#else
+#if !defined(javascript_HOST_ARCH)
     pPrPr_disableITimers, c_execvpe,
+    runInteractiveProcess_lock,
+#endif
     ignoreSignal, defaultSignal,
 #endif
     withFilePathException, withCEnvironment,
     translate,
-    fdToHandle,
+    createPipe,
+    createPipeFd,
+    interruptProcessGroupOf,
+    withForkWait,
+    ignoreSigPipe,
     ) where
 
 import Control.Concurrent
-import Control.Exception
-import Data.Bits
-import Data.String
+import Control.Exception (SomeException, mask, try, throwIO)
+import qualified Control.Exception as C
 import Foreign.C
-import Foreign.Marshal
-import Foreign.Ptr
-import Foreign.Storable
-import System.IO.Unsafe
-
-#if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
-import Control.Monad
-import Data.Char
 import System.IO
-import System.Posix.Process.Internals ( pPrPr_disableITimers, c_execvpe )
-import System.Posix.Types
-#endif
 
-#ifdef __GLASGOW_HASKELL__
-import System.Posix.Internals
-import GHC.IO.Exception
-import GHC.IO.Encoding
-import qualified GHC.IO.FD as FD
-import GHC.IO.Device
-import GHC.IO.Handle.FD
-import GHC.IO.Handle.Internals
-import GHC.IO.Handle.Types hiding (ClosedHandle)
-import System.IO.Error
-import Data.Typeable
-# if defined(mingw32_HOST_OS)
-import GHC.IO.IOMode
-import System.Win32.DebugApi (PHANDLE)
-# else
-import System.Posix.Signals as Sig
-# endif
-#endif
-
-#if defined(mingw32_HOST_OS)
-import System.Directory         ( doesFileExist )
-import System.Environment       ( getEnv )
-import System.FilePath
-#endif
-
-#include "HsProcessConfig.h"
-#include "processFlags.h"
-
-#ifdef mingw32_HOST_OS
-# if defined(i386_HOST_ARCH)
-#  define WINDOWS_CCONV stdcall
-# elif defined(x86_64_HOST_ARCH)
-#  define WINDOWS_CCONV ccall
-# else
-#  error Unknown mingw32 arch
-# endif
-#endif
-
--- ----------------------------------------------------------------------------
--- ProcessHandle type
-
-{- | A handle to a process, which can be used to wait for termination
-     of the process using 'System.Process.waitForProcess'.
-
-     None of the process-creation functions in this library wait for
-     termination: they all return a 'ProcessHandle' which may be used
-     to wait for the process later.
--}
-data ProcessHandle__ = OpenHandle PHANDLE | ClosedHandle ExitCode
-data ProcessHandle = ProcessHandle !(MVar ProcessHandle__) !Bool
-
-modifyProcessHandle
-        :: ProcessHandle
-        -> (ProcessHandle__ -> IO (ProcessHandle__, a))
-        -> IO a
-modifyProcessHandle (ProcessHandle m _) io = modifyMVar m io
-
-withProcessHandle
-        :: ProcessHandle
-        -> (ProcessHandle__ -> IO a)
-        -> IO a
-withProcessHandle (ProcessHandle m _) io = withMVar m io
-
-#if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
-
-type PHANDLE = CPid
-
-mkProcessHandle :: PHANDLE -> Bool -> IO ProcessHandle
-mkProcessHandle p mb_delegate_ctlc = do
-  m <- newMVar (OpenHandle p)
-  return (ProcessHandle m mb_delegate_ctlc)
+import GHC.IO.Exception ( IOErrorType(..), IOException(..) )
+import GHC.IO.Handle.FD (fdToHandle)
+import System.Posix.Internals (FD)
 
-closePHANDLE :: PHANDLE -> IO ()
-closePHANDLE _ = return ()
+import System.Process.Common
 
+#if defined(javascript_HOST_ARCH)
+import System.Process.JavaScript
+#elif defined(mingw32_HOST_OS)
+import System.Process.Windows
 #else
-
-throwErrnoIfBadPHandle :: String -> IO PHANDLE -> IO PHANDLE
-throwErrnoIfBadPHandle = throwErrnoIfNull
-
--- On Windows, we have to close this HANDLE when it is no longer required,
--- hence we add a finalizer to it
-mkProcessHandle :: PHANDLE -> IO ProcessHandle
-mkProcessHandle h = do
-   m <- newMVar (OpenHandle h)
-   _ <- mkWeakMVar m (processHandleFinaliser m)
-   return (ProcessHandle m False)
-
-processHandleFinaliser :: MVar ProcessHandle__ -> IO ()
-processHandleFinaliser m =
-   modifyMVar_ m $ \p_ -> do
-        case p_ of
-          OpenHandle ph -> closePHANDLE ph
-          _ -> return ()
-        return (error "closed process handle")
-
-closePHANDLE :: PHANDLE -> IO ()
-closePHANDLE ph = c_CloseHandle ph
-
-foreign import WINDOWS_CCONV unsafe "CloseHandle"
-  c_CloseHandle
-        :: PHANDLE
-        -> IO ()
+import System.Process.Posix
 #endif
 
 -- ----------------------------------------------------------------------------
-
-data CreateProcess = CreateProcess{
-  cmdspec      :: CmdSpec,                 -- ^ Executable & arguments, or shell command
-  cwd          :: Maybe FilePath,          -- ^ Optional path to the working directory for the new process
-  env          :: Maybe [(String,String)], -- ^ Optional environment (otherwise inherit from the current process)
-  std_in       :: StdStream,               -- ^ How to determine stdin
-  std_out      :: StdStream,               -- ^ How to determine stdout
-  std_err      :: StdStream,               -- ^ How to determine stderr
-  close_fds    :: Bool,                    -- ^ Close all file descriptors except stdin, stdout and stderr in the new process (on Windows, only works if std_in, std_out, and std_err are all Inherit)
-  create_group :: Bool,                    -- ^ Create a new process group
-  delegate_ctlc:: Bool,                    -- ^ Delegate control-C handling. Use this for interactive console processes to let them handle control-C themselves (see below for details).
-                                           --
-                                           --   On Windows this has no effect.
-                                           --
-                                           --   @since 1.2.0.0
-  detach_console :: Bool,                  -- ^ Use the windows DETACHED_PROCESS flag when creating the process; does nothing on other platforms.
-                                           --
-                                           --   @since 1.3.0.0
-  create_new_console :: Bool,              -- ^ Use the windows CREATE_NEW_CONSOLE flag when creating the process; does nothing on other platforms.
-                                           --
-                                           --   Default: @False@
-                                           --
-                                           --   @since 1.3.0.0
-  new_session :: Bool                      -- ^ Use posix setsid to start the new process in a new session; does nothing on other platforms.
-                                           --
-                                           --   @since 1.3.0.0
- }
-
-data CmdSpec
-  = ShellCommand String
-      -- ^ A command line to execute using the shell
-  | RawCommand FilePath [String]
-      -- ^ The name of an executable with a list of arguments
-      --
-      -- The 'FilePath' argument names the executable, and is interpreted
-      -- according to the platform's standard policy for searching for
-      -- executables. Specifically:
-      --
-      -- * on Unix systems the
-      --   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/execvp.html execvp(3)>
-      --   semantics is used, where if the executable filename does not
-      --   contain a slash (@/@) then the @PATH@ environment variable is
-      --   searched for the executable.
-      --
-      -- * on Windows systems the Win32 @CreateProcess@ semantics is used.
-      --   Briefly: if the filename does not contain a path, then the
-      --   directory containing the parent executable is searched, followed
-      --   by the current directory, then some standard locations, and
-      --   finally the current @PATH@.  An @.exe@ extension is added if the
-      --   filename does not already have an extension.  For full details
-      --   see the
-      --   <http://msdn.microsoft.com/en-us/library/windows/desktop/aa365527%28v=vs.85%29.aspx documentation>
-      --   for the Windows @SearchPath@ API.
-
-
--- | construct a `ShellCommand` from a string literal
---
--- @since 1.2.1.0
-instance IsString CmdSpec where
-  fromString = ShellCommand
-
-data StdStream
-  = Inherit                  -- ^ Inherit Handle from parent
-  | UseHandle Handle         -- ^ Use the supplied Handle
-  | CreatePipe               -- ^ Create a new pipe.  The returned
-                             -- @Handle@ will use the default encoding
-                             -- and newline translation mode (just
-                             -- like @Handle@s created by @openFile@).
-  | NoStream                 -- ^ No stream handle will be passed
-
 -- | This function is almost identical to
 -- 'System.Process.createProcess'. The only differences are:
 --
@@ -251,395 +95,16 @@
 --
 -- @since 1.2.1.0
 createProcess_
-  :: String                     -- ^ function name (for error messages)
+  :: String
+       -- ^ Function name (for error messages).
+       --
+       --   This can be any 'String', but will typically be the name of the caller.
+       --   E.g., 'spawnProcess' passes @"spawnProcess"@ here when calling
+       --   'createProcess_'.
   -> CreateProcess
   -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
-
-#if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
-
-#ifdef __GLASGOW_HASKELL__
-
--- -----------------------------------------------------------------------------
--- POSIX runProcess with signal handling in the child
-
-createProcess_ fun CreateProcess{ cmdspec = cmdsp,
-                                  cwd = mb_cwd,
-                                  env = mb_env,
-                                  std_in = mb_stdin,
-                                  std_out = mb_stdout,
-                                  std_err = mb_stderr,
-                                  close_fds = mb_close_fds,
-                                  create_group = mb_create_group,
-                                  delegate_ctlc = mb_delegate_ctlc,
-                                  detach_console = mb_detach_console,
-                                  create_new_console = mb_create_new_console,
-                                  new_session = mb_new_session }
- = do
-  let (cmd,args) = commandToProcess cmdsp
-  withFilePathException cmd $
-   alloca $ \ pfdStdInput  ->
-   alloca $ \ pfdStdOutput ->
-   alloca $ \ pfdStdError  ->
-   alloca $ \ pFailedDoing ->
-   maybeWith withCEnvironment mb_env $ \pEnv ->
-   maybeWith withFilePath mb_cwd $ \pWorkDir ->
-   withMany withFilePath (cmd:args) $ \cstrs ->
-   withArray0 nullPtr cstrs $ \pargs -> do
-
-     fdin  <- mbFd fun fd_stdin  mb_stdin
-     fdout <- mbFd fun fd_stdout mb_stdout
-     fderr <- mbFd fun fd_stderr mb_stderr
-
-     when mb_delegate_ctlc
-       startDelegateControlC
-
-     -- runInteractiveProcess() blocks signals around the fork().
-     -- Since blocking/unblocking of signals is a global state
-     -- operation, we better ensure mutual exclusion of calls to
-     -- runInteractiveProcess().
-     proc_handle <- withMVar runInteractiveProcess_lock $ \_ ->
-                         c_runInteractiveProcess pargs pWorkDir pEnv
-                                fdin fdout fderr
-                                pfdStdInput pfdStdOutput pfdStdError
-                                (if mb_delegate_ctlc then 1 else 0)
-                                ((if mb_close_fds then RUN_PROCESS_IN_CLOSE_FDS else 0)
-                                .|.(if mb_create_group then RUN_PROCESS_IN_NEW_GROUP else 0)
-                                .|.(if mb_detach_console then RUN_PROCESS_DETACHED else 0)
-                                .|.(if mb_create_new_console then RUN_PROCESS_NEW_CONSOLE else 0)
-                                .|.(if mb_new_session then RUN_PROCESS_NEW_SESSION else 0))
-                                pFailedDoing
-
-     when (proc_handle == -1) $ do
-         cFailedDoing <- peek pFailedDoing
-         failedDoing <- peekCString cFailedDoing
-         when mb_delegate_ctlc
-           stopDelegateControlC
-         throwErrno (fun ++ ": " ++ failedDoing)
-
-     hndStdInput  <- mbPipe mb_stdin  pfdStdInput  WriteMode
-     hndStdOutput <- mbPipe mb_stdout pfdStdOutput ReadMode
-     hndStdError  <- mbPipe mb_stderr pfdStdError  ReadMode
-
-     ph <- mkProcessHandle proc_handle mb_delegate_ctlc
-     return (hndStdInput, hndStdOutput, hndStdError, ph)
-
-{-# NOINLINE runInteractiveProcess_lock #-}
-runInteractiveProcess_lock :: MVar ()
-runInteractiveProcess_lock = unsafePerformIO $ newMVar ()
-
--- ----------------------------------------------------------------------------
--- Delegated control-C handling on Unix
-
--- See ticket https://ghc.haskell.org/trac/ghc/ticket/2301
--- and http://www.cons.org/cracauer/sigint.html
---
--- While running an interactive console process like ghci or a shell, we want
--- to let that process handle Ctl-C keyboard interrupts how it sees fit.
--- So that means we need to ignore the SIGINT/SIGQUIT Unix signals while we're
--- running such programs. And then if/when they do terminate, we need to check
--- if they terminated due to SIGINT/SIGQUIT and if so then we behave as if we
--- got the Ctl-C then, by throwing the UserInterrupt exception.
---
--- If we run multiple programs like this concurrently then we have to be
--- careful to avoid messing up the signal handlers. We keep a count and only
--- restore when the last one has finished.
-
-{-# NOINLINE runInteractiveProcess_delegate_ctlc #-}
-runInteractiveProcess_delegate_ctlc :: MVar (Maybe (Int, Sig.Handler, Sig.Handler))
-runInteractiveProcess_delegate_ctlc = unsafePerformIO $ newMVar Nothing
-
-startDelegateControlC :: IO ()
-startDelegateControlC =
-    modifyMVar_ runInteractiveProcess_delegate_ctlc $ \delegating -> do
-      case delegating of
-        Nothing -> do
-          -- We're going to ignore ^C in the parent while there are any
-          -- processes using ^C delegation.
-          --
-          -- If another thread runs another process without using
-          -- delegation while we're doing this then it will inherit the
-          -- ignore ^C status.
-          old_int  <- installHandler sigINT  Ignore Nothing
-          old_quit <- installHandler sigQUIT Ignore Nothing
-          return (Just (1, old_int, old_quit))
-
-        Just (count, old_int, old_quit) -> do
-          -- If we're already doing it, just increment the count
-          let !count' = count + 1
-          return (Just (count', old_int, old_quit))
-
-stopDelegateControlC :: IO ()
-stopDelegateControlC =
-    modifyMVar_ runInteractiveProcess_delegate_ctlc $ \delegating -> do
-      case delegating of
-        Just (1, old_int, old_quit) -> do
-          -- Last process, so restore the old signal handlers
-          _ <- installHandler sigINT  old_int  Nothing
-          _ <- installHandler sigQUIT old_quit Nothing
-          return Nothing
-
-        Just (count, old_int, old_quit) -> do
-          -- Not the last, just decrement the count
-          let !count' = count - 1
-          return (Just (count', old_int, old_quit))
-
-        Nothing -> return Nothing -- should be impossible
-
-endDelegateControlC :: ExitCode -> IO ()
-endDelegateControlC exitCode = do
-    stopDelegateControlC
-
-    -- And if the process did die due to SIGINT or SIGQUIT then
-    -- we throw our equivalent exception here (synchronously).
-    --
-    -- An alternative design would be to throw to the main thread, as the
-    -- normal signal handler does. But since we can be sync here, we do so.
-    -- It allows the code locally to catch it and do something.
-    case exitCode of
-      ExitFailure n | isSigIntQuit n -> throwIO UserInterrupt
-      _                              -> return ()
-  where
-    isSigIntQuit n = sig == sigINT || sig == sigQUIT
-      where
-        sig = fromIntegral (-n)
-
-foreign import ccall unsafe "runInteractiveProcess"
-  c_runInteractiveProcess
-        ::  Ptr CString
-        -> CString
-        -> Ptr CString
-        -> FD
-        -> FD
-        -> FD
-        -> Ptr FD
-        -> Ptr FD
-        -> Ptr FD
-        -> CInt                         -- reset child's SIGINT & SIGQUIT handlers
-        -> CInt                         -- flags
-        -> Ptr CString
-        -> IO PHANDLE
-
-#endif /* __GLASGOW_HASKELL__ */
-
-ignoreSignal, defaultSignal :: CLong
-ignoreSignal  = CONST_SIG_IGN
-defaultSignal = CONST_SIG_DFL
-
-#else
-
-#ifdef __GLASGOW_HASKELL__
-
-createProcess_ fun CreateProcess{ cmdspec = cmdsp,
-                                  cwd = mb_cwd,
-                                  env = mb_env,
-                                  std_in = mb_stdin,
-                                  std_out = mb_stdout,
-                                  std_err = mb_stderr,
-                                  close_fds = mb_close_fds,
-                                  create_group = mb_create_group,
-                                  delegate_ctlc = _ignored,
-                                  detach_console = mb_detach_console,
-                                  create_new_console = mb_create_new_console,
-                                  new_session = mb_new_session }
- = do
-  (cmd, cmdline) <- commandToProcess cmdsp
-  withFilePathException cmd $
-   alloca $ \ pfdStdInput  ->
-   alloca $ \ pfdStdOutput ->
-   alloca $ \ pfdStdError  ->
-   maybeWith withCEnvironment mb_env $ \pEnv ->
-   maybeWith withCWString mb_cwd $ \pWorkDir -> do
-   withCWString cmdline $ \pcmdline -> do
-
-     fdin  <- mbFd fun fd_stdin  mb_stdin
-     fdout <- mbFd fun fd_stdout mb_stdout
-     fderr <- mbFd fun fd_stderr mb_stderr
-
-     -- #2650: we must ensure mutual exclusion of c_runInteractiveProcess,
-     -- because otherwise there is a race condition whereby one thread
-     -- has created some pipes, and another thread spawns a process which
-     -- accidentally inherits some of the pipe handles that the first
-     -- thread has created.
-     --
-     -- An MVar in Haskell is the best way to do this, because there
-     -- is no way to do one-time thread-safe initialisation of a mutex
-     -- the C code.  Also the MVar will be cheaper when not running
-     -- the threaded RTS.
-     proc_handle <- withMVar runInteractiveProcess_lock $ \_ ->
-                    throwErrnoIfBadPHandle fun $
-                         c_runInteractiveProcess pcmdline pWorkDir pEnv
-                                fdin fdout fderr
-                                pfdStdInput pfdStdOutput pfdStdError
-                                ((if mb_close_fds then RUN_PROCESS_IN_CLOSE_FDS else 0)
-                                .|.(if mb_create_group then RUN_PROCESS_IN_NEW_GROUP else 0)
-                                .|.(if mb_detach_console then RUN_PROCESS_DETACHED else 0)
-                                .|.(if mb_create_new_console then RUN_PROCESS_NEW_CONSOLE else 0)
-                                .|.(if mb_new_session then RUN_PROCESS_NEW_SESSION else 0))
-
-     hndStdInput  <- mbPipe mb_stdin  pfdStdInput  WriteMode
-     hndStdOutput <- mbPipe mb_stdout pfdStdOutput ReadMode
-     hndStdError  <- mbPipe mb_stderr pfdStdError  ReadMode
-
-     ph <- mkProcessHandle proc_handle
-     return (hndStdInput, hndStdOutput, hndStdError, ph)
-
-{-# NOINLINE runInteractiveProcess_lock #-}
-runInteractiveProcess_lock :: MVar ()
-runInteractiveProcess_lock = unsafePerformIO $ newMVar ()
-
--- The following functions are always present in the export list. For
--- compatibility with the non-Windows code, we provide the same functions with
--- matching type signatures, but implemented as no-ops. For details, see:
--- <https://github.com/haskell/process/pull/21>
-startDelegateControlC :: IO ()
-startDelegateControlC = return ()
-
-endDelegateControlC :: ExitCode -> IO ()
-endDelegateControlC _ = return ()
-
-stopDelegateControlC :: IO ()
-stopDelegateControlC = return ()
-
--- End no-op functions
-
-foreign import ccall unsafe "runInteractiveProcess"
-  c_runInteractiveProcess
-        :: CWString
-        -> CWString
-        -> Ptr CWString
-        -> FD
-        -> FD
-        -> FD
-        -> Ptr FD
-        -> Ptr FD
-        -> Ptr FD
-        -> CInt                         -- flags
-        -> IO PHANDLE
-#endif
-
-#endif /* __GLASGOW_HASKELL__ */
-
-fd_stdin, fd_stdout, fd_stderr :: FD
-fd_stdin  = 0
-fd_stdout = 1
-fd_stderr = 2
-
-mbFd :: String -> FD -> StdStream -> IO FD
-mbFd _   _std CreatePipe      = return (-1)
-mbFd _fun std Inherit         = return std
-mbFd _fn _std NoStream        = return (-2)
-mbFd fun _std (UseHandle hdl) =
-  withHandle fun hdl $ \Handle__{haDevice=dev,..} ->
-    case cast dev of
-      Just fd -> do
-         -- clear the O_NONBLOCK flag on this FD, if it is set, since
-         -- we're exposing it externally (see #3316)
-         fd' <- FD.setNonBlockingMode fd False
-         return (Handle__{haDevice=fd',..}, FD.fdFD fd')
-      Nothing ->
-          ioError (mkIOError illegalOperationErrorType
-                      "createProcess" (Just hdl) Nothing
-                   `ioeSetErrorString` "handle is not a file descriptor")
-
-mbPipe :: StdStream -> Ptr FD -> IOMode -> IO (Maybe Handle)
-mbPipe CreatePipe pfd  mode = fmap Just (pfdToHandle pfd mode)
-mbPipe _std      _pfd _mode = return Nothing
-
-pfdToHandle :: Ptr FD -> IOMode -> IO Handle
-pfdToHandle pfd mode = do
-  fd <- peek pfd
-  let filepath = "fd:" ++ show fd
-  (fD,fd_type) <- FD.mkFD (fromIntegral fd) mode
-                       (Just (Stream,0,0)) -- avoid calling fstat()
-                       False {-is_socket-}
-                       False {-non-blocking-}
-  fD' <- FD.setNonBlockingMode fD True -- see #3316
-#if __GLASGOW_HASKELL__ >= 704
-  enc <- getLocaleEncoding
-#else
-  let enc = localeEncoding
-#endif
-  mkHandleFromFD fD' fd_type filepath mode False {-is_socket-} (Just enc)
-
--- ----------------------------------------------------------------------------
--- commandToProcess
-
-{- | Turns a shell command into a raw command.  Usually this involves
-     wrapping it in an invocation of the shell.
-
-   There's a difference in the signature of commandToProcess between
-   the Windows and Unix versions.  On Unix, exec takes a list of strings,
-   and we want to pass our command to /bin/sh as a single argument.
-
-   On Windows, CreateProcess takes a single string for the command,
-   which is later decomposed by cmd.exe.  In this case, we just want
-   to prepend @\"c:\WINDOWS\CMD.EXE \/c\"@ to our command line.  The
-   command-line translation that we normally do for arguments on
-   Windows isn't required (or desirable) here.
--}
-
-#if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
-
-commandToProcess :: CmdSpec -> (FilePath, [String])
-commandToProcess (ShellCommand string) = ("/bin/sh", ["-c", string])
-commandToProcess (RawCommand cmd args) = (cmd, args)
-
-#else
-
-commandToProcess
-  :: CmdSpec
-  -> IO (FilePath, String)
-commandToProcess (ShellCommand string) = do
-  cmd <- findCommandInterpreter
-  return (cmd, translate cmd ++ " /c " ++ string)
-        -- We don't want to put the cmd into a single
-        -- argument, because cmd.exe will not try to split it up.  Instead,
-        -- we just tack the command on the end of the cmd.exe command line,
-        -- which partly works.  There seem to be some quoting issues, but
-        -- I don't have the energy to find+fix them right now (ToDo). --SDM
-        -- (later) Now I don't know what the above comment means.  sigh.
-commandToProcess (RawCommand cmd args) = do
-  return (cmd, translate cmd ++ concatMap ((' ':) . translate) args)
-
--- Find CMD.EXE (or COMMAND.COM on Win98).  We use the same algorithm as
--- system() in the VC++ CRT (Vc7/crt/src/system.c in a VC++ installation).
-findCommandInterpreter :: IO FilePath
-findCommandInterpreter = do
-  -- try COMSPEC first
-  catchJust (\e -> if isDoesNotExistError e then Just e else Nothing)
-            (getEnv "COMSPEC") $ \_ -> do
-
-    -- try to find CMD.EXE or COMMAND.COM
-    {-
-    XXX We used to look at _osver (using cbits) and pick which shell to
-    use with
-    let filename | osver .&. 0x8000 /= 0 = "command.com"
-                 | otherwise             = "cmd.exe"
-    We ought to use GetVersionEx instead, but for now we just look for
-    either filename
-    -}
-    path <- getEnv "PATH"
-    let
-        -- use our own version of System.Directory.findExecutable, because
-        -- that assumes the .exe suffix.
-        search :: [FilePath] -> IO (Maybe FilePath)
-        search [] = return Nothing
-        search (d:ds) = do
-                let path1 = d </> "cmd.exe"
-                    path2 = d </> "command.com"
-                b1 <- doesFileExist path1
-                b2 <- doesFileExist path2
-                if b1 then return (Just path1)
-                      else if b2 then return (Just path2)
-                                 else search ds
-    --
-    mb_path <- search (splitSearchPath path)
-
-    case mb_path of
-      Nothing -> ioError (mkIOError doesNotExistErrorType
-                                "findCommandInterpreter" Nothing Nothing)
-      Just cmd -> return cmd
-#endif
+createProcess_ msg proc_ = unwrapHandles `fmap` createProcess_Internal msg proc_
+{-# INLINE createProcess_ #-}
 
 -- ------------------------------------------------------------------------
 -- Escaping commands for shells
@@ -697,55 +162,17 @@
 -}
 
 translate :: String -> String
-#if mingw32_HOST_OS
-translate xs = '"' : snd (foldr escape (True,"\"") xs)
-  where escape '"'  (_,     str) = (True,  '\\' : '"'  : str)
-        escape '\\' (True,  str) = (True,  '\\' : '\\' : str)
-        escape '\\' (False, str) = (False, '\\' : str)
-        escape c    (_,     str) = (False, c : str)
-        -- See long comment above for what this function is trying to do.
-        --
-        -- The Bool passed back along the string is True iff the
-        -- rest of the string is a sequence of backslashes followed by
-        -- a double quote.
-#else
-translate "" = "''"
-translate str
-   -- goodChar is a pessimistic predicate, such that if an argument is
-   -- non-empty and only contains goodChars, then there is no need to
-   -- do any quoting or escaping
- | all goodChar str = str
- | otherwise        = '\'' : foldr escape "'" str
-  where escape '\'' = showString "'\\''"
-        escape c    = showChar c
-        goodChar c = isAlphaNum c || c `elem` "-_.,/"
-#endif
-
--- ----------------------------------------------------------------------------
--- Utils
-
-withFilePathException :: FilePath -> IO a -> IO a
-withFilePathException fpath act = handle mapEx act
-  where
-    mapEx ex = ioError (ioeSetFileName ex fpath)
-
-#if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
-withCEnvironment :: [(String,String)] -> (Ptr CString  -> IO a) -> IO a
-withCEnvironment envir act =
-  let env' = map (\(name, val) -> name ++ ('=':val)) envir
-  in withMany withCString env' (\pEnv -> withArray0 nullPtr pEnv act)
-#else
-withCEnvironment :: [(String,String)] -> (Ptr CWString -> IO a) -> IO a
-withCEnvironment envir act =
-  let env' = foldr (\(name, val) env -> name ++ ('=':val)++'\0':env) "\0" envir
-  in withCWString env' (act . castPtr)
-#endif
+translate = translateInternal
+{-# INLINE translate #-}
 
+-- ---------------------------------------------------------------------------
+-- unwrapHandles
+unwrapHandles :: ProcRetHandles -> (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
+unwrapHandles r = (hStdInput r, hStdOutput r, hStdError r, procHandle r)
 
 -- ----------------------------------------------------------------------------
 -- Deprecated / compat
 
-#ifdef __GLASGOW_HASKELL__
 {-# DEPRECATED runGenProcess_
       "Please do not use this anymore, use the ordinary 'System.Process.createProcess'. If you need the SIGINT handling, use delegate_ctlc = True (runGenProcess_ is now just an imperfectly emulated stub that probably duplicates or overrides your own signal handling)." #-}
 runGenProcess_
@@ -754,12 +181,97 @@
  -> Maybe CLong                -- ^ handler for SIGINT
  -> Maybe CLong                -- ^ handler for SIGQUIT
  -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
-#if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
-runGenProcess_ fun c (Just sig) (Just sig') | sig == defaultSignal && sig == sig'
+runGenProcess_ fun c (Just sig) (Just sig') | isDefaultSignal sig && sig == sig'
                          = createProcess_ fun c { delegate_ctlc = True }
 runGenProcess_ fun c _ _ = createProcess_ fun c
-#else
-runGenProcess_ fun c _ _ = createProcess_ fun c
-#endif
 
-#endif
+-- ---------------------------------------------------------------------------
+-- createPipe
+
+-- | Create a pipe for interprocess communication and return a
+-- @(readEnd, writeEnd)@ `Handle` pair.
+--
+-- * WinIO Support
+--
+-- When this function is used with WinIO enabled it's the caller's
+-- responsibility to register the handles with the I/O manager.
+-- If this is not done the operation will deadlock.  Association can
+-- be done as follows:
+--
+-- @
+--     #if defined(__IO_MANAGER_WINIO__)
+--     import GHC.IO.SubSystem ((`<!>`))
+--     import GHC.IO.Handle.Windows (handleToHANDLE)
+--     import GHC.Event.Windows (associateHandle')
+--     #endif
+--
+--     ...
+--
+--     #if defined(__IO_MANAGER_WINIO__)
+--     return () \<!> do
+--       associateHandle' =\<\< handleToHANDLE readEnd
+--     #endif
+-- @
+--
+-- Only associate handles that you are in charge of read/writing to.
+-- Do not associate handles passed to another process.  It's the
+-- process's responsibility to register the handle if it supports
+-- async access.
+--
+-- @since 1.2.1.0
+createPipe :: IO (Handle, Handle)
+createPipe = createPipeInternal
+{-# INLINE createPipe #-}
+
+-- ---------------------------------------------------------------------------
+-- createPipeFd
+
+-- | Create a pipe for interprocess communication and return a
+-- @(readEnd, writeEnd)@ `FD` pair.
+--
+-- @since 1.4.2.0
+createPipeFd :: IO (FD, FD)
+createPipeFd = createPipeInternalFd
+{-# INLINE createPipeFd #-}
+
+
+-- ----------------------------------------------------------------------------
+-- interruptProcessGroupOf
+
+-- | Sends an interrupt signal to the process group of the given process.
+--
+-- On Unix systems, it sends the group the SIGINT signal.
+--
+-- On Windows systems, it generates a CTRL_BREAK_EVENT and will only work for
+-- processes created using 'createProcess' and setting the 'create_group' flag
+
+interruptProcessGroupOf
+    :: ProcessHandle    -- ^ A process in the process group
+    -> IO ()
+interruptProcessGroupOf = interruptProcessGroupOfInternal
+
+-- | Fork a thread while doing something else, but kill it if there's an
+-- exception.
+--
+-- This is important in the cases above because we want to kill the thread
+-- that is holding the Handle lock, because when we clean up the process we
+-- try to close that handle, which could otherwise deadlock.
+--
+-- @since 1.6.20.0
+withForkWait :: IO () -> (IO () ->  IO a) -> IO a
+withForkWait async body = do
+  waitVar <- newEmptyMVar :: IO (MVar (Either SomeException ()))
+  mask $ \restore -> do
+    tid <- forkIO $ try (restore async) >>= putMVar waitVar
+    let wait = takeMVar waitVar >>= either throwIO return
+    restore (body wait) `C.onException` killThread tid
+
+-- | Handle any SIGPIPE errors in the given computation.
+--
+-- @since 1.6.20.0
+ignoreSigPipe :: IO () -> IO ()
+ignoreSigPipe = C.handle $ \e -> case e of
+                                   IOError { ioe_type  = ResourceVanished
+                                           , ioe_errno = Just ioe }
+                                     | Errno ioe == ePIPE -> return ()
+                                   _ -> throwIO e
diff --git a/System/Process/JavaScript.hs b/System/Process/JavaScript.hs
new file mode 100644
--- /dev/null
+++ b/System/Process/JavaScript.hs
@@ -0,0 +1,308 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE JavaScriptFFI #-}
+{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE CPP #-}
+
+{-
+  Child process support for JavaScript running on the node.js platform.
+
+  Other platforms such as browsers will accept the JavaScript code, but all
+  operations will result in unsupported operation exceptions.
+ -}
+
+#include "HsProcessConfig.h"
+
+module System.Process.JavaScript
+    ( mkProcessHandle
+    , translateInternal
+    , createProcess_Internal
+    , withCEnvironment
+    , closePHANDLE
+    , startDelegateControlC
+    , endDelegateControlC
+    , stopDelegateControlC
+    , isDefaultSignal
+    , ignoreSignal
+    , defaultSignal
+    , createPipeInternal
+    , createPipeInternalFd
+    , interruptProcessGroupOfInternal
+    , getProcessId
+    , getCurrentProcessId
+    ) where
+
+import Control.Concurrent.MVar
+import Control.Exception (throwIO)
+
+import Data.Char (isAlphaNum)
+
+import System.Exit
+import System.IO
+import System.IO.Error
+import qualified System.Posix.Internals as Posix
+
+import Foreign.C
+import Foreign.Marshal
+import Foreign.Ptr
+
+import GHC.IO.Handle.FD (mkHandleFromFD)
+import GHC.IO.Device (IODeviceType(..))
+import GHC.IO.Encoding (getLocaleEncoding)
+import GHC.IO.Exception
+import qualified GHC.IO.FD as FD
+
+import GHC.JS.Prim
+
+import System.Process.Common hiding (mb_delegate_ctlc, mbPipe)
+
+mkProcessHandle :: JSVal -> Bool -> IO ProcessHandle
+mkProcessHandle p mb_delegate_ctlc = do
+  m <- newMVar (OpenHandle p)
+  ml <- newMVar ()
+  return (ProcessHandle m mb_delegate_ctlc ml)
+
+closePHANDLE :: JSVal -> IO ()
+closePHANDLE _ = return ()
+
+getProcessId :: PHANDLE -> IO Int
+getProcessId ph =
+  throwErrnoIfMinus1 "getProcessId" (js_getProcessId ph)
+
+getCurrentProcessId :: IO Int
+getCurrentProcessId =
+  throwErrnoIfMinus1 "getCurrentProcessId" js_getCurrentProcessId
+
+startDelegateControlC :: IO ()
+startDelegateControlC =
+  throwErrnoIfMinus1_ "startDelegateControlC" js_startDelegateControlC
+
+stopDelegateControlC :: IO ()
+stopDelegateControlC =
+  throwErrnoIfMinus1_ "stopDelegateControlC" js_stopDelegateControlC
+
+endDelegateControlC :: ExitCode -> IO ()
+endDelegateControlC (ExitFailure (-2)) = throwIO UserInterrupt -- SIGINT
+endDelegateControlC _                  = pure ()
+
+ignoreSignal, defaultSignal :: CLong
+ignoreSignal  = CONST_SIG_IGN
+defaultSignal = CONST_SIG_DFL
+
+isDefaultSignal :: CLong -> Bool
+isDefaultSignal = (== defaultSignal)
+
+interruptProcessGroupOfInternal
+    :: ProcessHandle    -- ^ A process in the process group
+    -> IO ()
+interruptProcessGroupOfInternal ph =
+      withProcessHandle ph $ \p_ -> do
+        case p_ of
+            OpenExtHandle{} -> return ()
+            ClosedHandle  _ -> return ()
+            OpenHandle    h ->
+                throwErrnoIfMinus1_ "interruptProcessGroupOfInternal"
+                                    (js_interruptProcessGroupOf h)
+
+translateInternal :: String -> String
+translateInternal "" = "''"
+translateInternal str
+   -- goodChar is a pessimistic predicate, such that if an argument is
+   -- non-empty and only contains goodChars, then there is no need to
+   -- do any quoting or escaping
+ | all goodChar str = str
+ | otherwise        = '\'' : foldr escape "'" str
+  where escape '\'' = showString "'\\''"
+        escape c    = showChar c
+        goodChar c = isAlphaNum c || c `elem` "-_.,/"
+
+-- node.js does not appear to have any built-in facilities
+-- for creating pipes, so we leave this as an unsupported operation
+-- for now
+createPipeInternal :: IO (Handle, Handle)
+createPipeInternal = ioError
+  (ioeSetLocation unsupportedOperation "createPipeInternal")
+
+createPipeInternalFd :: IO (Posix.FD, Posix.FD)
+createPipeInternalFd = ioError
+  (ioeSetLocation unsupportedOperation "createPipeInternalFd")
+
+withCEnvironment :: [(String,String)] -> (Ptr CString  -> IO a) -> IO a
+withCEnvironment envir act =
+  let env' = map (\(name, val) -> name ++ ('=':val)) envir
+  in withMany withCString env' (\pEnv -> withArray0 nullPtr pEnv act)
+
+commandToProcess :: CmdSpec -> IO (FilePath, [String])
+commandToProcess cmd =
+  case cmd of
+    ShellCommand xs   -> c2p (toJSString xs) jsNull
+    RawCommand c args -> c2p (toJSString c) =<< toJSStrings args
+  where
+    c2p c as = do
+      r <- throwErrnoIfJSNull "commandToProcess" (js_commandToProcess c as)
+      fromJSStrings r >>= \case
+        (x:xs) -> pure (x,xs)
+        _      -> error "commandToProcess: empty list"
+
+-- -----------------------------------------------------------------------------
+-- JavaScript nodejs runProcess with signal handling in the child
+
+createProcess_Internal
+  :: String
+       -- ^ Function name (for error messages).
+       --
+       --   This can be any 'String', but will typically be the name of the caller.
+       --   E.g., 'spawnProcess' passes @"spawnProcess"@ here when calling
+       --   'createProcess_'.
+  -> CreateProcess
+  -> IO ProcRetHandles
+createProcess_Internal fun CreateProcess{ cmdspec = cmdsp,
+                                  cwd = mb_cwd,
+                                  env = mb_env,
+                                  std_in = mb_stdin,
+                                  std_out = mb_stdout,
+                                  std_err = mb_stderr,
+                                  close_fds = mb_close_fds,
+                                  create_group = mb_create_group,
+                                  delegate_ctlc = mb_delegate_ctlc,
+                                  new_session = mb_new_session,
+                                  child_user = mb_child_user,
+                                  child_group = mb_child_group }
+ = do
+  (cmd, args) <- commandToProcess cmdsp
+  withFilePathException cmd $ do
+     fdin  <- mbFd fun fd_stdin  mb_stdin
+     fdout <- mbFd fun fd_stdout mb_stdout
+     fderr <- mbFd fun fd_stderr mb_stderr
+     env'  <- maybe (pure jsNull)
+                    (toJSStrings . concatMap (\(x,y) -> [x,y]))
+                    mb_env
+
+     let cwd' = maybe jsNull toJSString mb_cwd
+     let c1 = toJSString cmd
+     c2 <- case args of
+               [] -> return jsNull
+               _  -> toJSStrings args
+
+     r <- throwErrnoIfJSNull fun $
+             js_runInteractiveProcess c1
+                                      c2
+                                      cwd'
+                                      env'
+                                      fdin
+                                      fdout
+                                      fderr
+                                      mb_close_fds
+                                      mb_create_group
+                                      mb_delegate_ctlc
+                                      mb_new_session
+                                      (maybe (-1) fromIntegral mb_child_group)
+                                      (maybe (-1) fromIntegral mb_child_user)
+
+     fdin_r:fdout_r:fderr_r:_ <-
+         map (stdFD . fromIntegral) <$> (fromJSInts =<< getProp r "fds")
+
+     hndStdInput  <- mbPipe mb_stdin  fdin_r  WriteMode
+     hndStdOutput <- mbPipe mb_stdout fdout_r ReadMode
+     hndStdError  <- mbPipe mb_stderr fderr_r ReadMode
+
+     ph <- mkProcessHandle r mb_delegate_ctlc
+     return $ ProcRetHandles { hStdInput = hndStdInput
+                             , hStdOutput = hndStdOutput
+                             , hStdError = hndStdError
+                             , procHandle = ph
+                             }
+
+mbPipe :: StdStream -> FD.FD -> IOMode -> IO (Maybe Handle)
+mbPipe CreatePipe fd mode = do
+  enc <- getLocaleEncoding
+  fmap Just (mkHandleFromFD fd
+                            Stream
+                            ("fd: " ++ show fd)
+                            mode
+                            False {-is_socket-}
+                            (Just enc))
+mbPipe _ _ _ = do
+  return Nothing
+
+stdFD :: CInt -> FD.FD
+stdFD fd = FD.FD { FD.fdFD = fd
+                 , FD.fdIsNonBlocking = 0
+                 }
+
+-- -----------------------------------------------------------------------------
+-- Some helpers for dealing with JavaScript values
+
+-- JavaScript value type synonyms, for readability
+type JSArray  = JSVal
+type JSString = JSVal
+
+fromJSStrings :: JSVal -> IO [String]
+fromJSStrings x = fmap (map fromJSString) (fromJSArray x)
+
+fromJSInts :: JSVal -> IO [Int]
+fromJSInts x = map fromJSInt <$> fromJSArray x
+
+toJSStrings :: [String] -> IO JSVal
+toJSStrings xs = toJSArray (map toJSString xs)
+
+throwErrnoIfJSNull :: String -> IO JSVal -> IO JSVal
+throwErrnoIfJSNull msg m = do
+  r <- m
+  if isNull r then throwErrno msg
+              else return r
+
+-- -----------------------------------------------------------------------------
+-- Foreign imports from process.js
+
+-- run an interactive process. Note that this foreign import is asynchronous
+-- (interruptible) since it waits until the process has spawned (or an error
+-- has occurred.
+--
+-- this should only be a short time, so it should be safe to call this from
+-- an uninterruptible mask.
+
+foreign import javascript interruptible "h$process_runInteractiveProcess"
+  js_runInteractiveProcess
+        :: JSString     -- ^ command or program
+        -> JSArray      -- ^ arguments, null if it's a raw command
+        -> JSString     -- ^ working dir, null for current
+        -> JSArray      -- ^ environment, null for existing
+        -> CInt         -- ^ stdin fd
+        -> CInt         -- ^ stdout fd
+        -> CInt         -- ^ stderr fd
+        -> Bool         -- ^ close file descriptors in child (currently unsupported)
+        -> Bool         -- ^ create a new process group
+        -> Bool         -- ^ delegate ctrl-c
+        -> Bool         -- ^ create a new session
+        -> Int          -- ^ set child GID (-1 for unchanged)
+        -> Int          -- ^ set child UID (-1 for unchanged)
+        -> IO JSVal     -- ^ process handle (null if an error occurred)
+
+foreign import javascript safe "h$process_commandToProcess"
+  js_commandToProcess
+        :: JSString
+        -> JSArray
+        -> IO JSArray
+
+foreign import javascript unsafe "h$process_interruptProcessGroupOf"
+  js_interruptProcessGroupOf
+        :: PHANDLE
+        -> IO Int
+
+foreign import javascript unsafe "h$process_startDelegateControlC"
+  js_startDelegateControlC
+        :: IO Int
+
+foreign import javascript unsafe "h$process_stopDelegateControlC"
+  js_stopDelegateControlC
+        :: IO Int
+
+foreign import javascript unsafe "h$process_getCurrentProcessId"
+  js_getCurrentProcessId
+        :: IO Int
+
+foreign import javascript unsafe "h$process_getProcessId"
+  js_getProcessId
+        :: PHANDLE
+        -> IO Int
diff --git a/System/Process/Posix.hs b/System/Process/Posix.hs
new file mode 100644
--- /dev/null
+++ b/System/Process/Posix.hs
@@ -0,0 +1,343 @@
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE CPP #-}
+
+#include <ghcplatform.h>
+
+module System.Process.Posix
+    ( mkProcessHandle
+    , translateInternal
+    , createProcess_Internal
+    , withCEnvironment
+    , closePHANDLE
+    , startDelegateControlC
+    , endDelegateControlC
+    , stopDelegateControlC
+    , isDefaultSignal
+    , ignoreSignal
+    , defaultSignal
+    , c_execvpe
+    , pPrPr_disableITimers
+    , createPipeInternal
+    , createPipeInternalFd
+    , interruptProcessGroupOfInternal
+    , runInteractiveProcess_lock
+    ) where
+
+import Control.Concurrent
+import Control.Exception
+import Data.Bits
+import Foreign.C
+import Foreign.Marshal
+import Foreign.Ptr
+import Foreign.Storable
+import System.IO.Unsafe
+
+import Control.Monad
+import Data.Char
+import System.IO
+import System.Posix.Process.Internals ( pPrPr_disableITimers, c_execvpe )
+import System.Posix.Types
+
+import System.Posix.Internals
+import GHC.IO.Exception
+import System.Posix.Signals as Sig
+import qualified System.Posix.IO as Posix
+import System.Posix.Process (getProcessGroupIDOf)
+
+import System.Process.Common hiding (mb_delegate_ctlc)
+
+#if defined(wasm32_HOST_ARCH)
+import System.IO.Error
+#endif
+
+#include "HsProcessConfig.h"
+#include "processFlags.h"
+
+mkProcessHandle :: PHANDLE -> Bool -> IO ProcessHandle
+mkProcessHandle p mb_delegate_ctlc = do
+  m <- newMVar (OpenHandle p)
+  l <- newMVar ()
+  return (ProcessHandle m mb_delegate_ctlc l)
+
+closePHANDLE :: PHANDLE -> IO ()
+closePHANDLE _ = return ()
+
+-- ----------------------------------------------------------------------------
+-- commandToProcess
+
+{- | Turns a shell command into a raw command.  Usually this involves
+     wrapping it in an invocation of the shell.
+
+   There's a difference in the signature of commandToProcess between
+   the Windows and Unix versions.  On Unix, exec takes a list of strings,
+   and we want to pass our command to /bin/sh as a single argument.
+
+   On Windows, CreateProcess takes a single string for the command,
+   which is later decomposed by cmd.exe.  In this case, we just want
+   to prepend @\"c:\WINDOWS\CMD.EXE \/c\"@ to our command line.  The
+   command-line translation that we normally do for arguments on
+   Windows isn't required (or desirable) here.
+-}
+
+commandToProcess :: CmdSpec -> (FilePath, [String])
+commandToProcess (ShellCommand string) = ("/bin/sh", ["-c", string])
+commandToProcess (RawCommand cmd args) = (cmd, args)
+
+translateInternal :: String -> String
+translateInternal "" = "''"
+translateInternal str
+   -- goodChar is a pessimistic predicate, such that if an argument is
+   -- non-empty and only contains goodChars, then there is no need to
+   -- do any quoting or escaping
+ | all goodChar str = str
+ | otherwise        = '\'' : foldr escape "'" str
+  where escape '\'' = showString "'\\''"
+        escape c    = showChar c
+        goodChar c = isAlphaNum c || c `elem` "-_.,/"
+
+-- ----------------------------------------------------------------------------
+-- Utils
+
+withCEnvironment :: [(String,String)] -> (Ptr CString  -> IO a) -> IO a
+withCEnvironment envir act =
+  let env' = map (\(name, val) -> name ++ ('=':val)) envir
+  in withMany withFilePath env' (\pEnv -> withArray0 nullPtr pEnv act)
+
+-- -----------------------------------------------------------------------------
+-- POSIX runProcess with signal handling in the child
+
+createProcess_Internal
+    :: String
+    -> CreateProcess
+    -> IO ProcRetHandles
+createProcess_Internal fun
+                   CreateProcess{ cmdspec = cmdsp,
+                                  cwd = mb_cwd,
+                                  env = mb_env,
+                                  std_in = mb_stdin,
+                                  std_out = mb_stdout,
+                                  std_err = mb_stderr,
+                                  close_fds = mb_close_fds,
+                                  create_group = mb_create_group,
+                                  delegate_ctlc = mb_delegate_ctlc,
+                                  detach_console = mb_detach_console,
+                                  create_new_console = mb_create_new_console,
+                                  new_session = mb_new_session,
+                                  child_group = mb_child_group,
+                                  child_user = mb_child_user }
+ = do
+  let (cmd,args) = commandToProcess cmdsp
+  withFilePathException cmd $
+   alloca $ \ pfdStdInput  ->
+   alloca $ \ pfdStdOutput ->
+   alloca $ \ pfdStdError  ->
+   alloca $ \ pFailedDoing ->
+   maybeWith withCEnvironment mb_env $ \pEnv ->
+   maybeWith withFilePath mb_cwd $ \pWorkDir ->
+   maybeWith with mb_child_group $ \pChildGroup ->
+   maybeWith with mb_child_user $ \pChildUser ->
+   withFilePath cmd $ \cmdstr ->
+   withMany withCString args $ \argstrs -> do
+   let cstrs = cmdstr : argstrs
+   withArray0 nullPtr cstrs $ \pargs -> do
+
+     fdin  <- mbFd fun fd_stdin  mb_stdin
+     fdout <- mbFd fun fd_stdout mb_stdout
+     fderr <- mbFd fun fd_stderr mb_stderr
+
+     when mb_delegate_ctlc
+       startDelegateControlC
+
+     let flags = (if mb_close_fds then RUN_PROCESS_IN_CLOSE_FDS else 0)
+                  .|.(if mb_create_group then RUN_PROCESS_IN_NEW_GROUP else 0)
+                  .|.(if mb_detach_console then RUN_PROCESS_DETACHED else 0)
+                  .|.(if mb_create_new_console then RUN_PROCESS_NEW_CONSOLE else 0)
+                  .|.(if mb_new_session then RUN_PROCESS_NEW_SESSION else 0)
+                  .|.(if mb_delegate_ctlc then RESET_INT_QUIT_HANDLERS else 0)
+
+     -- See the comment on runInteractiveProcess_lock
+     proc_handle <- withMVar runInteractiveProcess_lock $ \_ ->
+                         c_runInteractiveProcess pargs pWorkDir pEnv
+                                fdin fdout fderr
+                                pfdStdInput pfdStdOutput pfdStdError
+                                pChildGroup pChildUser
+                                flags
+                                pFailedDoing
+
+     when (proc_handle == -1) $ do
+         cFailedDoing <- peek pFailedDoing
+         failedDoing <- peekCString cFailedDoing
+         when mb_delegate_ctlc
+           stopDelegateControlC
+         throwErrno (fun ++ ": " ++ failedDoing)
+
+     hndStdInput  <- mbPipe mb_stdin  pfdStdInput  WriteMode
+     hndStdOutput <- mbPipe mb_stdout pfdStdOutput ReadMode
+     hndStdError  <- mbPipe mb_stderr pfdStdError  ReadMode
+
+     ph <- mkProcessHandle proc_handle mb_delegate_ctlc
+     return ProcRetHandles { hStdInput    = hndStdInput
+                           , hStdOutput   = hndStdOutput
+                           , hStdError    = hndStdError
+                           , procHandle   = ph
+                           }
+
+{-# NOINLINE runInteractiveProcess_lock #-}
+-- | 'runInteractiveProcess' blocks signals around the fork().
+-- Since blocking/unblocking of signals is a global state operation, we need to
+-- ensure mutual exclusion of calls to 'runInteractiveProcess'.
+-- This lock is exported so that other libraries which also need to fork()
+-- (and also need to make the same global state changes) can protect their changes
+-- with the same lock.
+-- See https://github.com/haskell/process/pull/154.
+--
+-- @since 1.6.6.0
+runInteractiveProcess_lock :: MVar ()
+runInteractiveProcess_lock = unsafePerformIO $ newMVar ()
+
+-- ----------------------------------------------------------------------------
+-- Delegated control-C handling on Unix
+
+-- See ticket https://ghc.haskell.org/trac/ghc/ticket/2301
+-- and http://www.cons.org/cracauer/sigint.html
+--
+-- While running an interactive console process like ghci or a shell, we want
+-- to let that process handle Ctl-C keyboard interrupts how it sees fit.
+-- So that means we need to ignore the SIGINT/SIGQUIT Unix signals while we're
+-- running such programs. And then if/when they do terminate, we need to check
+-- if they terminated due to SIGINT/SIGQUIT and if so then we behave as if we
+-- got the Ctl-C then, by throwing the UserInterrupt exception.
+--
+-- If we run multiple programs like this concurrently then we have to be
+-- careful to avoid messing up the signal handlers. We keep a count and only
+-- restore when the last one has finished.
+
+{-# NOINLINE runInteractiveProcess_delegate_ctlc #-}
+runInteractiveProcess_delegate_ctlc :: MVar (Maybe (Int, Sig.Handler, Sig.Handler))
+runInteractiveProcess_delegate_ctlc = unsafePerformIO $ newMVar Nothing
+
+startDelegateControlC :: IO ()
+startDelegateControlC =
+    modifyMVar_ runInteractiveProcess_delegate_ctlc $ \delegating -> do
+      case delegating of
+        Nothing -> do
+          -- We're going to ignore ^C in the parent while there are any
+          -- processes using ^C delegation.
+          --
+          -- If another thread runs another process without using
+          -- delegation while we're doing this then it will inherit the
+          -- ignore ^C status.
+          old_int  <- installHandler sigINT  Ignore Nothing
+          old_quit <- installHandler sigQUIT Ignore Nothing
+          return (Just (1, old_int, old_quit))
+
+        Just (count, old_int, old_quit) -> do
+          -- If we're already doing it, just increment the count
+          let !count' = count + 1
+          return (Just (count', old_int, old_quit))
+
+stopDelegateControlC :: IO ()
+stopDelegateControlC =
+    modifyMVar_ runInteractiveProcess_delegate_ctlc $ \delegating -> do
+      case delegating of
+        Just (1, old_int, old_quit) -> do
+          -- Last process, so restore the old signal handlers
+          _ <- installHandler sigINT  old_int  Nothing
+          _ <- installHandler sigQUIT old_quit Nothing
+          return Nothing
+
+        Just (count, old_int, old_quit) -> do
+          -- Not the last, just decrement the count
+          let !count' = count - 1
+          return (Just (count', old_int, old_quit))
+
+        Nothing -> return Nothing -- should be impossible
+
+endDelegateControlC :: ExitCode -> IO ()
+endDelegateControlC exitCode = do
+    stopDelegateControlC
+
+    -- And if the process did die due to SIGINT or SIGQUIT then
+    -- we throw our equivalent exception here (synchronously).
+    --
+    -- An alternative design would be to throw to the main thread, as the
+    -- normal signal handler does. But since we can be sync here, we do so.
+    -- It allows the code locally to catch it and do something.
+    case exitCode of
+      ExitFailure n | isSigIntQuit n -> throwIO UserInterrupt
+      _                              -> return ()
+  where
+    isSigIntQuit n = sig == sigINT || sig == sigQUIT
+      where
+        sig = fromIntegral (-n)
+
+#if defined(wasm32_HOST_ARCH)
+
+c_runInteractiveProcess
+        ::  Ptr CString
+        -> CString
+        -> Ptr CString
+        -> FD
+        -> FD
+        -> FD
+        -> Ptr FD
+        -> Ptr FD
+        -> Ptr FD
+        -> Ptr CGid
+        -> Ptr CUid
+        -> CInt                         -- flags
+        -> Ptr CString
+        -> IO PHANDLE
+c_runInteractiveProcess _ _ _ _ _ _ _ _ _ _ _ _ _ = ioError (ioeSetLocation unsupportedOperation "runInteractiveProcess")
+
+#else
+
+foreign import ccall unsafe "runInteractiveProcess"
+  c_runInteractiveProcess
+        ::  Ptr CString
+        -> CString
+        -> Ptr CString
+        -> FD
+        -> FD
+        -> FD
+        -> Ptr FD
+        -> Ptr FD
+        -> Ptr FD
+        -> Ptr CGid
+        -> Ptr CUid
+        -> CInt                         -- flags
+        -> Ptr CString
+        -> IO PHANDLE
+
+#endif
+
+ignoreSignal, defaultSignal :: CLong
+ignoreSignal  = CONST_SIG_IGN
+defaultSignal = CONST_SIG_DFL
+
+isDefaultSignal :: CLong -> Bool
+isDefaultSignal = (== defaultSignal)
+
+createPipeInternal :: IO (Handle, Handle)
+createPipeInternal = do
+    (readfd, writefd) <- Posix.createPipe
+    readh <- Posix.fdToHandle readfd
+    writeh <- Posix.fdToHandle writefd
+    return (readh, writeh)
+
+createPipeInternalFd :: IO (FD, FD)
+createPipeInternalFd = do
+   (Fd readfd, Fd writefd) <- Posix.createPipe
+   return (readfd, writefd)
+
+interruptProcessGroupOfInternal
+    :: ProcessHandle    -- ^ A process in the process group
+    -> IO ()
+interruptProcessGroupOfInternal ph = do
+    withProcessHandle ph $ \p_ -> do
+        case p_ of
+            OpenExtHandle{} -> return ()
+            ClosedHandle  _ -> return ()
+            OpenHandle    h -> do
+                pgid <- getProcessGroupIDOf h
+                signalProcessGroup sigINT pgid
diff --git a/System/Process/Windows.hsc b/System/Process/Windows.hsc
new file mode 100644
--- /dev/null
+++ b/System/Process/Windows.hsc
@@ -0,0 +1,603 @@
+{-# LANGUAGE CPP, ForeignFunctionInterface #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE InterruptibleFFI #-}
+module System.Process.Windows
+    ( mkProcessHandle
+    , translateInternal
+    , createProcess_Internal
+    , withCEnvironment
+    , closePHANDLE
+    , startDelegateControlC
+    , endDelegateControlC
+    , stopDelegateControlC
+    , isDefaultSignal
+    , createPipeInternal
+    , createPipeInternalFd
+    , interruptProcessGroupOfInternal
+    , terminateJob
+    , terminateJobUnsafe
+    , waitForJobCompletion
+    , timeout_Infinite
+    , HANDLE
+    , mkNamedPipe
+    ) where
+
+import System.Process.Common
+import Control.Concurrent
+import Control.Exception
+import Control.Monad
+import Data.Bits
+import Data.Char (toLower)
+import Data.List (dropWhileEnd)
+import Foreign.C
+import Foreign.Marshal
+import Foreign.Ptr
+import Foreign.Storable
+import System.IO.Unsafe
+
+import System.Posix.Internals
+import GHC.IO.Exception
+##if defined(__IO_MANAGER_WINIO__)
+import GHC.IO.SubSystem
+import qualified GHC.Event.Windows as Mgr
+import Graphics.Win32.Misc
+##endif
+import GHC.IO.Handle.FD
+import GHC.IO.Handle.Types hiding (ClosedHandle)
+import System.IO.Error
+import System.IO (IOMode(..))
+
+import System.Directory         ( doesFileExist )
+import System.Environment       ( getEnv )
+import System.FilePath
+import System.Win32.Console (generateConsoleCtrlEvent, cTRL_BREAK_EVENT)
+import System.Win32.Process (getProcessId)
+
+-- The double hash is used so that hsc does not process this include file
+##include "processFlags.h"
+
+#include <fcntl.h>     /* for _O_BINARY */
+
+##if defined(i386_HOST_ARCH)
+## define WINDOWS_CCONV stdcall
+##elif defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH)
+## define WINDOWS_CCONV ccall
+##else
+## error Unknown mingw32 arch
+##endif
+
+throwErrnoIfBadPHandle :: String -> IO PHANDLE -> IO PHANDLE
+throwErrnoIfBadPHandle = throwErrnoIfNull
+
+-- On Windows, we have to close this HANDLE when it is no longer required,
+-- hence we add a finalizer to it
+mkProcessHandle :: PHANDLE -> Bool -> PHANDLE -> IO ProcessHandle
+mkProcessHandle h ignore_signals job = do
+   m <- if job == nullPtr
+           then newMVar (OpenHandle h)
+           else newMVar (OpenExtHandle h job)
+   _ <- mkWeakMVar m (processHandleFinaliser m)
+   l <- newMVar ()
+   return (ProcessHandle m ignore_signals l)
+
+processHandleFinaliser :: MVar ProcessHandle__ -> IO ()
+processHandleFinaliser m =
+   modifyMVar_ m $ \p_ -> do
+        case p_ of
+          OpenHandle ph           -> closePHANDLE ph
+          OpenExtHandle ph job    -> closePHANDLE ph
+                                  >> closePHANDLE job
+          _ -> return ()
+        return (error "closed process handle")
+
+closePHANDLE :: PHANDLE -> IO ()
+closePHANDLE ph = c_CloseHandle ph
+
+foreign import WINDOWS_CCONV unsafe "CloseHandle"
+  c_CloseHandle
+        :: PHANDLE
+        -> IO ()
+
+createProcess_Internal
+  :: String                     -- ^ function name (for error messages)
+  -> CreateProcess
+  -> IO ProcRetHandles
+
+##if defined(__IO_MANAGER_WINIO__)
+createProcess_Internal = createProcess_Internal_mio <!> createProcess_Internal_winio
+##else
+createProcess_Internal = createProcess_Internal_mio
+##endif
+
+createProcess_Internal_mio
+  :: String                     -- ^ function name (for error messages)
+  -> CreateProcess
+  -> IO ProcRetHandles
+
+createProcess_Internal_mio fun def@CreateProcess{
+    std_in = mb_stdin,
+    std_out = mb_stdout,
+    std_err = mb_stderr,
+    close_fds = mb_close_fds,
+    create_group = mb_create_group,
+    detach_console = mb_detach_console,
+    create_new_console = mb_create_new_console,
+    new_session = mb_new_session,
+    use_process_jobs = use_job }
+ = createProcess_Internal_wrapper fun def $
+       \pfdStdInput pfdStdOutput pfdStdError hJob pEnv pWorkDir pcmdline -> do
+       fdin  <- mbFd fun fd_stdin  mb_stdin
+       fdout <- mbFd fun fd_stdout mb_stdout
+       fderr <- mbFd fun fd_stderr mb_stderr
+
+       -- #2650: we must ensure mutual exclusion of c_runInteractiveProcess,
+       -- because otherwise there is a race condition whereby one thread
+       -- has created some pipes, and another thread spawns a process which
+       -- accidentally inherits some of the pipe handles that the first
+       -- thread has created.
+       --
+       -- An MVar in Haskell is the best way to do this, because there
+       -- is no way to do one-time thread-safe initialisation of a mutex
+       -- the C code.  Also the MVar will be cheaper when not running
+       -- the threaded RTS.
+       proc_handle <- withMVar runInteractiveProcess_lock $ \_ ->
+                      throwErrnoIfBadPHandle fun $
+                           c_runInteractiveProcess pcmdline pWorkDir pEnv
+                                  fdin fdout fderr
+                                  pfdStdInput pfdStdOutput pfdStdError
+                                  ((if mb_close_fds then RUN_PROCESS_IN_CLOSE_FDS else 0)
+                                  .|.(if mb_create_group then RUN_PROCESS_IN_NEW_GROUP else 0)
+                                  .|.(if mb_detach_console then RUN_PROCESS_DETACHED else 0)
+                                  .|.(if mb_create_new_console then RUN_PROCESS_NEW_CONSOLE else 0)
+                                  .|.(if mb_new_session then RUN_PROCESS_NEW_SESSION else 0))
+                                  use_job
+                                  hJob
+
+       hndStdInput  <- mbPipe mb_stdin  pfdStdInput  WriteMode
+       hndStdOutput <- mbPipe mb_stdout pfdStdOutput ReadMode
+       hndStdError  <- mbPipe mb_stderr pfdStdError  ReadMode
+
+       return (proc_handle, hndStdInput, hndStdOutput, hndStdError)
+
+
+createProcess_Internal_wrapper
+  :: Storable a => String                     -- ^ function name (for error messages)
+  -> CreateProcess
+  -> (Ptr a -> Ptr a -> Ptr a -> Ptr PHANDLE -> Ptr CWString -> CWString
+      -> CWString -> IO (PHANDLE, Maybe Handle, Maybe Handle, Maybe Handle))
+  -> IO ProcRetHandles
+
+createProcess_Internal_wrapper _fun CreateProcess{
+    cmdspec = cmdsp,
+    cwd = mb_cwd,
+    env = mb_env,
+    delegate_ctlc = ignore_signals }
+    action
+ = do
+  let lenPtr = sizeOf (undefined :: WordPtr)
+  (cmd, cmdline) <- commandToProcess cmdsp
+  withFilePathException cmd $
+   alloca $ \ pfdStdInput           ->
+   alloca $ \ pfdStdOutput          ->
+   alloca $ \ pfdStdError           ->
+   allocaBytes lenPtr $ \ hJob      ->
+   maybeWith withCEnvironment mb_env $ \pEnv ->
+   maybeWith withCWString mb_cwd $ \pWorkDir -> do
+   withCWString cmdline $ \pcmdline -> do
+
+     (proc_handle, hndStdInput, hndStdOutput, hndStdError)
+       <- action pfdStdInput pfdStdOutput pfdStdError hJob pEnv pWorkDir pcmdline
+
+     -- If we have successfully created the process then check if we have to
+     -- detach from the console.  I'm not sure why the posix version changes
+     -- the state right before creating the child process, but doing so here
+     -- means the first child also inherits this
+     when ignore_signals $
+       startDelegateControlC
+
+     phJob  <- peek hJob
+     ph     <- mkProcessHandle proc_handle ignore_signals phJob
+     return ProcRetHandles { hStdInput  = hndStdInput
+                           , hStdOutput = hndStdOutput
+                           , hStdError  = hndStdError
+                           , procHandle = ph
+                           }
+
+##if defined(__IO_MANAGER_WINIO__)
+createProcess_Internal_winio
+  :: String                     -- ^ function name (for error messages)
+  -> CreateProcess
+  -> IO ProcRetHandles
+
+createProcess_Internal_winio fun def@CreateProcess{
+    std_in = mb_stdin,
+    std_out = mb_stdout,
+    std_err = mb_stderr,
+    close_fds = mb_close_fds,
+    create_group = mb_create_group,
+    detach_console = mb_detach_console,
+    create_new_console = mb_create_new_console,
+    new_session = mb_new_session,
+    use_process_jobs = use_job }
+ = createProcess_Internal_wrapper fun def $
+       \pfdStdInput pfdStdOutput pfdStdError hJob pEnv pWorkDir pcmdline -> do
+
+     _stdin  <- getStdHandle sTD_INPUT_HANDLE
+     _stdout <- getStdHandle sTD_OUTPUT_HANDLE
+     _stderr <- getStdHandle sTD_ERROR_HANDLE
+     hwnd_in  <- mbHANDLE _stdin  mb_stdin
+     hwnd_out <- mbHANDLE _stdout mb_stdout
+     hwnd_err <- mbHANDLE _stderr mb_stderr
+
+     -- #2650: we must ensure mutual exclusion of c_runInteractiveProcess,
+     -- because otherwise there is a race condition whereby one thread
+     -- has created some pipes, and another thread spawns a process which
+     -- accidentally inherits some of the pipe handles that the first
+     -- thread has created.
+     --
+     -- An MVar in Haskell is the best way to do this, because there
+     -- is no way to do one-time thread-safe initialisation of a mutex
+     -- the C code.  Also the MVar will be cheaper when not running
+     -- the threaded RTS.
+     proc_handle <- withMVar runInteractiveProcess_lock $ \_ ->
+                    throwErrnoIfBadPHandle fun $
+                         c_runInteractiveProcessHANDLE pcmdline pWorkDir pEnv
+                                hwnd_in hwnd_out hwnd_err
+                                pfdStdInput pfdStdOutput pfdStdError
+                                ((if mb_close_fds then RUN_PROCESS_IN_CLOSE_FDS else 0)
+                                .|.(if mb_create_group then RUN_PROCESS_IN_NEW_GROUP else 0)
+                                .|.(if mb_detach_console then RUN_PROCESS_DETACHED else 0)
+                                .|.(if mb_create_new_console then RUN_PROCESS_NEW_CONSOLE else 0)
+                                .|.(if mb_new_session then RUN_PROCESS_NEW_SESSION else 0))
+                                use_job
+                                hJob
+
+     -- Attach the handle to the I/O manager's CompletionPort.  This allows the
+     -- I/O manager to service requests for this Handle.
+     Mgr.associateHandle' =<< peek pfdStdInput
+     Mgr.associateHandle' =<< peek pfdStdOutput
+     Mgr.associateHandle' =<< peek pfdStdError
+
+     -- Create the haskell mode handles as files.
+     hndStdInput  <- mbPipeHANDLE mb_stdin  pfdStdInput  WriteMode
+     hndStdOutput <- mbPipeHANDLE mb_stdout pfdStdOutput ReadMode
+     hndStdError  <- mbPipeHANDLE mb_stderr pfdStdError  ReadMode
+
+     return (proc_handle, hndStdInput, hndStdOutput, hndStdError)
+
+##endif
+
+{-# NOINLINE runInteractiveProcess_lock #-}
+runInteractiveProcess_lock :: MVar ()
+runInteractiveProcess_lock = unsafePerformIO $ newMVar ()
+
+-- ----------------------------------------------------------------------------
+-- Delegated control-C handling on Windows
+
+-- See https://learn.microsoft.com/en-us/windows/console/setconsolectrlhandler
+--
+-- While running an interactive console process like ghci or a shell, we want
+-- to let that process handle Ctl-C keyboard interrupts how it sees fit.
+-- So that means we need to ignore the CTRL_C_EVENT/CTRL_BREAK_EVENT Windows
+-- events while we're running such programs.
+--
+-- If we run multiple programs like this concurrently then we have to be
+-- careful to avoid messing up the signal handlers. We keep a count and only
+-- restore when the last one has finished.
+--
+-- To do this we have to use SetConsoleCtrlHandler which masks the events for
+-- the current process and any child it creates from that point.
+--
+-- In this case we can't use FreeConsole/AttachConsole since those destroy
+-- the signal handler stack for the application when called.  This means we'd
+-- have to recreate them and process doesn't know what's there.
+
+{-# NOINLINE runInteractiveProcess_delegate_ctlc #-}
+runInteractiveProcess_delegate_ctlc :: MVar (Maybe (Int))
+runInteractiveProcess_delegate_ctlc = unsafePerformIO $ newMVar Nothing
+
+startDelegateControlC :: IO ()
+startDelegateControlC =
+    modifyMVar_ runInteractiveProcess_delegate_ctlc $ \delegating -> do
+      case delegating of
+        Nothing -> do
+          -- We're going to ignore ^C in the parent while there are any
+          -- processes using ^C delegation.
+          --
+          -- If another thread runs another process without using
+          -- delegation while we're doing this then it will inherit the
+          -- ignore ^C status.
+          _ <- c_setConsoleCtrlHandler nullPtr True
+          return (Just 1)
+
+        Just count -> do
+          -- If we're already doing it, just increment the count
+          let !count' = count + 1
+          return (Just count')
+
+stopDelegateControlC :: IO ()
+stopDelegateControlC =
+    modifyMVar_ runInteractiveProcess_delegate_ctlc $ \delegating -> do
+      case delegating of
+        Just 1 -> do
+          -- Last process, so restore the old signal handlers
+          _ <- c_setConsoleCtrlHandler nullPtr False
+          return Nothing
+
+        Just count -> do
+          -- Not the last, just decrement the count
+          let !count' = count - 1
+          return (Just count')
+
+        Nothing -> return Nothing -- should be impossible
+
+endDelegateControlC :: ExitCode -> IO ()
+-- I don't think there's a standard exit code for program interruptions
+-- on Windows, so I'll just ignore it for now.
+endDelegateControlC _ = stopDelegateControlC
+
+
+-- End no-op functions
+
+
+-- ----------------------------------------------------------------------------
+-- Interface to C I/O CP bits
+
+-- | Variant of terminateJob that is not thread-safe
+terminateJobUnsafe :: ProcessHandle__ -> CUInt -> IO Bool
+terminateJobUnsafe p_  ecode = do
+        case p_ of
+            ClosedHandle      _ -> return False
+            OpenHandle        _ -> return False
+            OpenExtHandle _ job -> c_terminateJobObject job ecode
+
+terminateJob :: ProcessHandle -> CUInt -> IO Bool
+terminateJob jh ecode =
+    withProcessHandle jh $ \p_ -> terminateJobUnsafe p_ ecode
+
+timeout_Infinite :: CUInt
+timeout_Infinite = 0xFFFFFFFF
+
+waitForJobCompletion :: PHANDLE -- ^ job handle
+                     -> IO ()
+waitForJobCompletion job =
+    throwErrnoIf_ not "waitForJobCompletion" $ c_waitForJobCompletion job
+
+-- ----------------------------------------------------------------------------
+-- Interface to C bits
+
+foreign import WINDOWS_CCONV unsafe "TerminateJobObject"
+  c_terminateJobObject
+        :: PHANDLE
+        -> CUInt
+        -> IO Bool
+
+foreign import WINDOWS_CCONV unsafe "SetConsoleCtrlHandler"
+  c_setConsoleCtrlHandler
+        :: Ptr ()
+        -> Bool
+        -> IO Bool
+
+foreign import ccall interruptible "waitForJobCompletion" -- NB. safe - can block
+  c_waitForJobCompletion
+        :: PHANDLE
+        -> IO Bool
+
+foreign import ccall unsafe "runInteractiveProcess"
+  c_runInteractiveProcess
+        :: CWString
+        -> CWString
+        -> Ptr CWString
+        -> FD
+        -> FD
+        -> FD
+        -> Ptr FD
+        -> Ptr FD
+        -> Ptr FD
+        -> CInt          -- flags
+        -> Bool          -- useJobObject
+        -> Ptr PHANDLE       -- Handle to Job
+        -> IO PHANDLE
+
+##if defined(__IO_MANAGER_WINIO__)
+foreign import ccall unsafe "runInteractiveProcessHANDLE"
+  c_runInteractiveProcessHANDLE
+        :: CWString
+        -> CWString
+        -> Ptr CWString
+        -> HANDLE
+        -> HANDLE
+        -> HANDLE
+        -> Ptr HANDLE
+        -> Ptr HANDLE
+        -> Ptr HANDLE
+        -> CInt          -- flags
+        -> Bool          -- useJobObject
+        -> Ptr PHANDLE       -- Handle to Job
+        -> IO PHANDLE
+##endif
+
+commandToProcess
+  :: CmdSpec
+  -> IO (FilePath, String)
+commandToProcess (ShellCommand string) = do
+  cmd <- findCommandInterpreter
+  return (cmd, translateInternal cmd ++ " /c " ++ string)
+        -- We don't want to put the cmd into a single
+        -- argument, because cmd.exe will not try to split it up.  Instead,
+        -- we just tack the command on the end of the cmd.exe command line,
+        -- which partly works.  There seem to be some quoting issues, but
+        -- I don't have the energy to find+fix them right now (ToDo). --SDM
+        -- (later) Now I don't know what the above comment means.  sigh.
+commandToProcess (RawCommand cmd args)
+  | map toLower (takeWinExtension cmd) `elem` [".bat", ".cmd"]
+  = return (cmd, translateInternal cmd ++ concatMap ((' ':) . translateCmdExeArg) args)
+  | otherwise
+  = return (cmd, translateInternal cmd ++ concatMap ((' ':) . translateInternal) args)
+
+-- TODO: filepath should also be updated with 'takeWinExtension'. Perhaps
+-- some day we can remove this logic from `process` but there is no hurry.
+
+-- | Get the extension of a Windows file, removing any trailing spaces or dots
+-- since they are ignored.
+--
+-- See: <https://learn.microsoft.com/en-us/troubleshoot/windows-client/shell-experience/file-folder-name-whitespace-characters>
+--
+-- >>> takeWinExtension "test.bat."
+-- ".bat"
+--
+-- >>> takeWinExtension "test.bat ."
+-- ".bat"
+takeWinExtension :: FilePath -> String
+takeWinExtension = takeExtension . dropWhileEnd (`elem` [' ', '.'])
+
+-- Find CMD.EXE (or COMMAND.COM on Win98).  We use the same algorithm as
+-- system() in the VC++ CRT (Vc7/crt/src/system.c in a VC++ installation).
+findCommandInterpreter :: IO FilePath
+findCommandInterpreter = do
+  -- try COMSPEC first
+  catchJust (\e -> if isDoesNotExistError e then Just e else Nothing)
+            (getEnv "COMSPEC") $ \_ -> do
+
+    -- try to find CMD.EXE or COMMAND.COM
+    {-
+    XXX We used to look at _osver (using cbits) and pick which shell to
+    use with
+    let filename | osver .&. 0x8000 /= 0 = "command.com"
+                 | otherwise             = "cmd.exe"
+    We ought to use GetVersionEx instead, but for now we just look for
+    either filename
+    -}
+    path <- getEnv "PATH"
+    let
+        -- use our own version of System.Directory.findExecutable, because
+        -- that assumes the .exe suffix.
+        search :: [FilePath] -> IO (Maybe FilePath)
+        search [] = return Nothing
+        search (d:ds) = do
+                let path1 = d </> "cmd.exe"
+                    path2 = d </> "command.com"
+                b1 <- doesFileExist path1
+                b2 <- doesFileExist path2
+                if b1 then return (Just path1)
+                      else if b2 then return (Just path2)
+                                 else search ds
+    --
+    mb_path <- search (splitSearchPath path)
+
+    case mb_path of
+      Nothing -> ioError (mkIOError doesNotExistErrorType
+                                "findCommandInterpreter" Nothing Nothing)
+      Just cmd -> return cmd
+
+-- | Alternative regime used to escape arguments destined for scripts
+-- interpreted by @cmd.exe@, (e.g. @.bat@ and @.cmd@ files).
+--
+-- This respects the Windows command interpreter's quoting rules:
+--
+-- * the entire argument should be surrounded in quotes
+-- * the backslash symbol is used to escape quotes and backslashes
+-- * the carat symbol is used to escape other special characters with
+--   significance to the interpreter
+--
+-- It is particularly important that we perform this quoting as
+-- unvalidated unquoted command-line arguments can be used to achieve
+-- arbitrary user code execution in when passed to a vulnerable batch
+-- script.
+--
+translateCmdExeArg :: String -> String
+translateCmdExeArg xs = "^\"" ++ snd (foldr escape (True,"^\"") xs)
+  where escape '"'  (_,     str) = (True,  '\\' : '"'  : str)
+        escape '\\' (True,  str) = (True,  '\\' : '\\' : str)
+        escape '\\' (False, str) = (False, '\\' : str)
+        escape '%'  (_,     str) = (False, "%%cd:~,%" ++ str)
+        escape c    (_,     str)
+          | c `elem` "^<>|&()"   = (False, '^' : c : str)
+          | otherwise            = (False,       c : str)
+
+translateInternal :: String -> String
+translateInternal xs = '"' : snd (foldr escape (True,"\"") xs)
+  where escape '"'  (_,     str) = (True,  '\\' : '"'  : str)
+        escape '\\' (True,  str) = (True,  '\\' : '\\' : str)
+        escape '\\' (False, str) = (False, '\\' : str)
+        escape c    (_,     str) = (False, c : str)
+        -- See long comment above for what this function is trying to do.
+        --
+        -- The Bool passed back along the string is True iff the
+        -- rest of the string is a sequence of backslashes followed by
+        -- a double quote.
+
+withCEnvironment :: [(String,String)] -> (Ptr CWString -> IO a) -> IO a
+withCEnvironment envir act =
+  let env' = foldr (\(name, val) env0 -> name ++ ('=':val)++'\0':env0) "\0" envir
+  in withCWString env' (act . castPtr)
+
+isDefaultSignal :: CLong -> Bool
+isDefaultSignal = const False
+
+createPipeInternal :: IO (Handle, Handle)
+##if defined(__IO_MANAGER_WINIO__)
+createPipeInternal = createPipeInternalPosix <!> createPipeInternalHANDLE
+##else
+createPipeInternal = createPipeInternalPosix
+##endif
+
+createPipeInternalPosix :: IO (Handle, Handle)
+createPipeInternalPosix = do
+    (readfd, writefd) <- createPipeInternalFd
+    (do readh <- fdToHandle readfd
+        writeh <- fdToHandle writefd
+        return (readh, writeh)) `onException` (close' readfd >> close' writefd)
+
+createPipeInternalFd :: IO (FD, FD)
+createPipeInternalFd = do
+    allocaArray 2 $ \ pfds -> do
+        throwErrnoIfMinus1_ "_pipe" $ c__pipe pfds 8192 (#const _O_BINARY)
+        readfd <- peek pfds
+        writefd <- peekElemOff pfds 1
+        return (readfd, writefd)
+
+##if defined(__IO_MANAGER_WINIO__)
+createPipeInternalHANDLE :: IO (Handle, Handle)
+createPipeInternalHANDLE =
+  alloca $ \ pfdStdInput  ->
+   alloca $ \ pfdStdOutput -> do
+     throwErrnoIf_  (==False) "mkNamedPipe" $
+       mkNamedPipe pfdStdInput True False pfdStdOutput True False
+     Just hndStdInput  <- mbPipeHANDLE CreatePipe pfdStdInput ReadMode
+     Just hndStdOutput <- mbPipeHANDLE CreatePipe pfdStdOutput WriteMode
+     return (hndStdInput, hndStdOutput)
+
+##endif
+
+foreign import ccall "mkNamedPipe" mkNamedPipe ::
+  Ptr HANDLE -> Bool -> Bool -> Ptr HANDLE -> Bool -> Bool -> IO Bool
+
+close' :: CInt -> IO ()
+close' = throwErrnoIfMinus1_ "_close" . c__close
+
+foreign import ccall "io.h _pipe" c__pipe ::
+    Ptr CInt -> CUInt -> CInt -> IO CInt
+
+foreign import ccall "io.h _close" c__close ::
+    CInt -> IO CInt
+
+interruptProcessGroupOfInternal
+    :: ProcessHandle    -- ^ A process in the process group
+    -> IO ()
+interruptProcessGroupOfInternal ph = do
+    withProcessHandle ph $ \p_ -> do
+        case p_ of
+            ClosedHandle _ -> return ()
+            _ -> do let h = phdlProcessHandle p_
+#if mingw32_HOST_OS
+                    pid <- getProcessId h
+                    generateConsoleCtrlEvent cTRL_BREAK_EVENT pid
+-- We can't use an #elif here, because MIN_VERSION_unix isn't defined
+-- on Windows, so on Windows cpp fails:
+-- error: missing binary operator before token "("
+#else
+                    pgid <- getProcessGroupIDOf h
+                    signalProcessGroup sigINT pgid
+#endif
+                    return ()
diff --git a/aclocal.m4 b/aclocal.m4
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -8,7 +8,7 @@
 # is supported in autoconf versions 2.50 up to the actual 2.57, so there is
 # little risk.
 AC_DEFUN([FP_COMPUTE_INT],
-[_AC_COMPUTE_INT([$1], [$2], [$3], [$4])[]dnl
+[AC_COMPUTE_INT([$2],[$1],[$3],[$4])[]dnl
 ])# FP_COMPUTE_INT
 
 
@@ -31,8 +31,7 @@
 # ---------------------------------------
 # autoheader helper for FP_CHECK_CONSTS
 m4_define([FP_CHECK_CONSTS_TEMPLATE],
-[AC_FOREACH([fp_Const], [$1],
-  [AH_TEMPLATE(AS_TR_CPP(CONST_[]fp_Const),
+[m4_foreach_w([fp_Const],[$1],[AH_TEMPLATE(AS_TR_CPP(CONST_[]fp_Const),
                [The value of ]fp_Const[.])])[]dnl
 ])# FP_CHECK_CONSTS_TEMPLATE
 
diff --git a/cbits/posix/common.h b/cbits/posix/common.h
new file mode 100644
--- /dev/null
+++ b/cbits/posix/common.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include "runProcess.h"
+
+enum std_handle_behavior {
+    // Close the handle
+    STD_HANDLE_CLOSE,
+    // dup2 the specified fd to standard handle
+    STD_HANDLE_USE_FD,
+    // dup2 the appropriate end of the given pipe to the standard handle and
+    // close the other end.
+    STD_HANDLE_USE_PIPE
+};
+
+struct std_handle {
+    enum std_handle_behavior behavior;
+    union {
+        int use_fd;
+        struct {
+            int parent_end, child_end;
+        } use_pipe;
+    };
+};
+
+int get_max_fd(void);
+
+// defined in find_executable.c
+#if !defined(HAVE_EXECVPE)
+char *find_executable(char *workingDirectory, char *filename);
+#endif
+
+// defined in fork_exec.c
+#if defined(HAVE_FORK)
+ProcHandle
+do_spawn_fork (char *const args[],
+               char *workingDirectory, char **environment,
+               struct std_handle *stdInHdl,
+               struct std_handle *stdOutHdl,
+               struct std_handle *stdErrHdl,
+               gid_t *childGroup, uid_t *childUser,
+               int flags,
+               char **failed_doing);
+#endif
+
+// defined in posix_spawn.c
+ProcHandle
+do_spawn_posix (char *const args[],
+                char *workingDirectory, char **environment,
+                struct std_handle *stdInHdl,
+                struct std_handle *stdOutHdl,
+                struct std_handle *stdErrHdl,
+                gid_t *childGroup, uid_t *childUser,
+                int flags,
+                char **failed_doing);
diff --git a/cbits/posix/find_executable.c b/cbits/posix/find_executable.c
new file mode 100644
--- /dev/null
+++ b/cbits/posix/find_executable.c
@@ -0,0 +1,149 @@
+/* ----------------------------------------------------------------------------
+ * search path search logic
+ * (c) Ben Gamari 2021
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#include "common.h"
+
+// the below is only necessary when we need to emulate execvpe.
+#if !defined(HAVE_EXECVPE)
+
+/* A quick check for whether the given path is absolute. */
+static bool is_absolute(const char *path) {
+    return path[0] == '/';
+}
+
+static char *concat_paths(const char *path1, const char *path2) {
+    if (is_absolute(path2)) {
+        return strdup(path2);
+    } else {
+        int len = strlen(path1) + 1 + strlen(path2) + 1;
+        char *tmp = malloc(len);
+        int ret = snprintf(tmp, len, "%s/%s", path1, path2);
+        if (ret < 0) {
+            free(tmp);
+            return NULL;
+        }
+        return tmp;
+    }
+}
+
+/* Return true if the given file exists and is an executable, optionally
+ * relative to the given working directory.
+ */
+static bool is_executable(char *working_dir, const char *path) {
+    if (working_dir && !is_absolute(path)) {
+        char *tmp = concat_paths(working_dir, path);
+        bool ret = access(tmp, X_OK) == 0;
+        free(tmp);
+        return ret;
+    } else {
+        return access(path, X_OK) == 0;
+    }
+}
+
+/* Find an executable with the given filename in the given search path. The
+ * result must be freed by the caller. Returns NULL if a matching file is not
+ * found.
+  */
+static char *find_in_search_path(char *working_dir, char *search_path, const char *filename) {
+    const int filename_len = strlen(filename);
+    char *tokbuf;
+    char *path = strtok_r(search_path, ":", &tokbuf);
+    if (!working_dir)
+        working_dir = ".";
+    int workdir_len = strlen(working_dir);
+    while (path != NULL) {
+	// N.B. gcc 6.3.0, used by Debian 9, inexplicably warns that `path`
+	// may not be initialised with -Wall.  Silence this warning. See #210.
+#if defined(__GNUC__) && __GNUC__ == 6 && __GNUC_MINOR__ == 3
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+        char *tmp;
+        if (is_absolute(path)) {
+            const int tmp_len = strlen(path) + 1 + filename_len + 1;
+            tmp = malloc(tmp_len);
+            snprintf(tmp, tmp_len, "%s/%s", path, filename);
+        } else {
+            const int tmp_len = workdir_len + 1 + strlen(path) + 1 + filename_len + 1;
+            tmp = malloc(tmp_len);
+            snprintf(tmp, tmp_len, "%s/%s/%s", working_dir, path, filename);
+        }
+#if defined(__GNUC__) && __GNUC__ == 6 && __GNUC_MINOR__ == 3
+#pragma GCC diagnostic pop
+#endif
+
+        if (is_executable(working_dir, tmp)) {
+            return tmp;
+        } else {
+            free(tmp);
+        }
+
+        path = strtok_r(NULL, ":", &tokbuf);
+    }
+    return NULL;
+}
+
+/* Identify the executable search path. The result must be freed by the caller. */
+static char *get_executable_search_path(void) {
+    char *search_path;
+
+    search_path = getenv("PATH");
+    if (search_path) {
+        search_path = strdup(search_path);
+        return search_path;
+    }
+
+#if defined(HAVE_CONFSTR)
+    int len = confstr(_CS_PATH, NULL, 0);
+    search_path = malloc(len + 1)
+    if (search_path != NULL) {
+        search_path[0] = ':';
+        (void) confstr (_CS_PATH, search_path + 1, len);
+        return search_path;
+    }
+#endif
+
+    return strdup(":");
+}
+
+/* Find the given executable in the executable search path relative to
+ * workingDirectory (or the current directory, if NULL).
+ * N.B. the caller is responsible for free()ing the result.
+ */
+char *find_executable(char *working_dir, char *filename) {
+    /* Drop trailing slash from working directory if necessary */
+    if (working_dir) {
+        int workdir_len = strlen(working_dir);
+        if (working_dir[workdir_len-1] == '/') {
+            working_dir[workdir_len-1] = '\0';
+        }
+    }
+
+    if (is_absolute(filename)) {
+        /* If it's an absolute path name, it's easy. */
+        return filename;
+
+    } else if (strchr(filename, '/')) {
+        /* If it's a relative path name, we must look for executables relative
+         * to the working directory. */
+        if (is_executable(working_dir, filename)) {
+            return filename;
+        }
+    }
+
+    /* Otherwise look through the search path... */
+    char *search_path = get_executable_search_path();
+    char *result = find_in_search_path(working_dir, search_path, filename);
+    free(search_path);
+    return result;
+}
+
+#endif
diff --git a/cbits/posix/fork_exec.c b/cbits/posix/fork_exec.c
new file mode 100644
--- /dev/null
+++ b/cbits/posix/fork_exec.c
@@ -0,0 +1,356 @@
+/* Ensure that execvpe and pipe2 are provided if possible */
+#define _GNU_SOURCE 1
+
+/* Ensure getpwuid_r(3) is available on Solaris. */
+#if defined(__sun)
+#define _POSIX_PTHREAD_SEMANTICS
+#endif
+
+#include "common.h"
+
+#if defined(HAVE_FORK)
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#if !(defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32))
+#include <pwd.h>
+#include <grp.h>
+#endif
+
+#if defined(HAVE_FCNTL_H)
+#include <fcntl.h>
+#endif
+
+#if defined(HAVE_SIGNAL_H)
+#include <signal.h>
+#endif
+
+#include <Rts.h>
+
+#if !defined(HAVE_WORKING_FORK)
+#error Cannot find a working fork command
+#endif
+
+// Rts internal API, not exposed in a public header file:
+extern void blockUserSignals(void);
+extern void unblockUserSignals(void);
+
+__attribute__((__noreturn__))
+static void
+child_failed(int pipe, const char *failed_doing) {
+    int err;
+    ssize_t unused __attribute__((unused));
+
+    err = errno;
+    // Having the child send the failed_doing pointer across the pipe is safe as
+    // we know that the child still has the same address space as the parent.
+    unused = write(pipe, &failed_doing, sizeof(failed_doing));
+    unused = write(pipe, &err,         sizeof(err));
+    // As a fallback, exit
+    _exit(127);
+}
+
+static int
+setup_std_handle_fork(int fd,
+                      struct std_handle *b,
+                      int pipe)
+{
+    switch (b->behavior) {
+    case STD_HANDLE_CLOSE:
+        if (close(fd) == -1 && errno != EBADF) {
+            child_failed(pipe, "close");
+        }
+        return 0;
+
+    case STD_HANDLE_USE_FD:
+        // N.B. POSIX specifies that dup2(x,x) should be a no-op, but
+        // naturally Apple ignores this and rather fails in posix_spawn on Big
+        // Sur.
+        if (b->use_fd != fd) {
+            if (dup2(b->use_fd,  fd) == -1) {
+                child_failed(pipe, "dup2");
+            }
+        }
+        return 0;
+
+    case STD_HANDLE_USE_PIPE:
+        if (b->use_pipe.child_end != fd) {
+            if (dup2(b->use_pipe.child_end, fd) == -1) {
+                child_failed(pipe, "dup2(child_end)");
+            }
+            if (close(b->use_pipe.child_end) == -1) {
+                child_failed(pipe, "close(child_end)");
+            }
+        }
+        if (close(b->use_pipe.parent_end) == -1) {
+            child_failed(pipe, "close(parent_end)");
+        }
+	return 0;
+
+    default:
+	// N.B. this should be unreachable but some compilers apparently can't
+	// see this.
+        child_failed(pipe, "setup_std_handle_fork(invalid behavior)");
+    }
+}
+
+/* This will `dup` the given fd such that it does not fall in the range of
+ * stdin/stdout/stderr, if necessary. The new handle will have O_CLOEXEC.
+ *
+ * This is necessary as we must ensure that the fork communications pipe does
+ * not inhabit fds 0 through 2 since we will need to manipulate these fds in
+ * setup_std_handle_fork while keeping the pipe available so that it can report
+ * errors. See #266.
+ */
+int unshadow_pipe_fd(int fd, char **failed_doing) {
+    if (fd > 2) {
+        return fd;
+    }
+
+    int new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+    if (new_fd == -1) {
+        *failed_doing = "fcntl(F_DUP_FD)";
+        return -1;
+    }
+    close(fd);
+    return new_fd;
+}
+
+/* Try spawning with fork. */
+ProcHandle
+do_spawn_fork (char *const args[],
+               char *workingDirectory, char **environment,
+               struct std_handle *stdInHdl,
+               struct std_handle *stdOutHdl,
+               struct std_handle *stdErrHdl,
+               gid_t *childGroup, uid_t *childUser,
+               int flags,
+               char **failed_doing)
+{
+    int forkCommunicationFds[2];
+    int r;
+
+#if defined(HAVE_PIPE2)
+    r = pipe2(forkCommunicationFds, O_CLOEXEC);
+#else
+    r = pipe(forkCommunicationFds);
+#endif
+    if (r == -1) {
+        *failed_doing = "pipe";
+        return -1;
+    }
+
+    // Ensure that the pipe fds don't shadow stdin/stdout/stderr
+    forkCommunicationFds[0] = unshadow_pipe_fd(forkCommunicationFds[0], failed_doing);
+    if (forkCommunicationFds[0] == -1) {
+        return -1;
+    }
+    forkCommunicationFds[1] = unshadow_pipe_fd(forkCommunicationFds[1], failed_doing);
+    if (forkCommunicationFds[1] == -1) {
+        return -1;
+    }
+
+    // N.B. execvpe is not supposed on some platforms. In this case
+    // we emulate this using fork and exec. However, to safely do so
+    // we need to perform all allocations *prior* to forking. Consequently, we
+    // need to find_executable before forking.
+#if !defined(HAVE_EXECVPE)
+    char *exec_path;
+    if (environment) {
+        exec_path = find_executable(workingDirectory, args[0]);
+        if (exec_path == NULL) {
+            errno = -ENOENT;
+            *failed_doing = "find_executable";
+            return -1;
+        }
+    }
+#endif
+
+    // Block signals with Haskell handlers.  The danger here is that
+    // with the threaded RTS, a signal arrives in the child process,
+    // the RTS writes the signal information into the pipe (which is
+    // shared between parent and child), and the parent behaves as if
+    // the signal had been raised.
+    blockUserSignals();
+
+    // See #4074.  Sometimes fork() gets interrupted by the timer
+    // signal and keeps restarting indefinitely.
+    stopTimer();
+
+    int pid = fork();
+    switch(pid)
+    {
+    case -1:
+        unblockUserSignals();
+        startTimer();
+        close(forkCommunicationFds[0]);
+        close(forkCommunicationFds[1]);
+        *failed_doing = "fork";
+        return -1;
+
+    case 0:
+        close(forkCommunicationFds[0]);
+        fcntl(forkCommunicationFds[1], F_SETFD, FD_CLOEXEC);
+
+        if ((flags & RUN_PROCESS_NEW_SESSION) != 0) {
+            setsid();
+        }
+        if ((flags & RUN_PROCESS_IN_NEW_GROUP) != 0) {
+            setpgid(0, 0);
+        }
+
+        if (childGroup) {
+            if (setgid( *childGroup) != 0) {
+                // ERROR
+                child_failed(forkCommunicationFds[1], "setgid");
+            }
+        }
+
+        if (childUser) {
+            // Using setuid properly first requires that we initgroups.
+            // However, to do this we must know the username of the user we are
+            // switching to.
+            struct passwd pw;
+            struct passwd *res = NULL;
+            int buf_len = sysconf(_SC_GETPW_R_SIZE_MAX);
+            // TODO: Strictly speaking malloc is a no-no after fork() since it
+            // may try to take a lock
+            char *buf = malloc(buf_len);
+            gid_t suppl_gid = childGroup ? *childGroup : getgid();
+            if ( getpwuid_r(*childUser, &pw, buf, buf_len, &res) != 0) {
+                child_failed(forkCommunicationFds[1], "getpwuid");
+            }
+            if ( res == NULL ) {
+                child_failed(forkCommunicationFds[1], "getpwuid");
+            }
+            if ( initgroups(res->pw_name, suppl_gid) != 0) {
+                child_failed(forkCommunicationFds[1], "initgroups");
+            }
+            if ( setuid( *childUser) != 0) {
+                // ERROR
+                child_failed(forkCommunicationFds[1], "setuid");
+            }
+        }
+
+        unblockUserSignals();
+
+        if (workingDirectory) {
+            if (chdir (workingDirectory) < 0) {
+                child_failed(forkCommunicationFds[1], "chdir");
+            }
+        }
+
+        // Note [Ordering of handle closing]
+        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        // Ordering matters here.  If any of the FDs
+        // 0,1,2 were initially closed, then our pipes may have used
+        // these FDs.  So when we dup2 the pipe FDs down to 0,1,2, we
+        // must do it in that order, otherwise we could overwrite an
+        // FD that we need later. See ticket #431.
+
+        setup_std_handle_fork(STDIN_FILENO,  stdInHdl,  forkCommunicationFds[1]);
+        setup_std_handle_fork(STDOUT_FILENO, stdOutHdl, forkCommunicationFds[1]);
+        setup_std_handle_fork(STDERR_FILENO, stdErrHdl, forkCommunicationFds[1]);
+
+        if ((flags & RUN_PROCESS_IN_CLOSE_FDS) != 0) {
+            int max_fd = get_max_fd();
+            // XXX Not the pipe
+            for (int i = 3; i < max_fd; i++) {
+                if (i != forkCommunicationFds[1]) {
+                    close(i);
+                }
+            }
+        }
+
+        /* Reset the SIGINT/SIGQUIT signal handlers in the child, if requested
+         */
+        if ((flags & RESET_INT_QUIT_HANDLERS) != 0) {
+            struct sigaction dfl;
+            (void)sigemptyset(&dfl.sa_mask);
+            dfl.sa_flags = 0;
+            dfl.sa_handler = SIG_DFL;
+            (void)sigaction(SIGINT,  &dfl, NULL);
+            (void)sigaction(SIGQUIT, &dfl, NULL);
+        }
+
+        /* the child */
+        if (environment) {
+#if defined(HAVE_EXECVPE)
+            // XXX Check result
+            execvpe(args[0], args, environment);
+            child_failed(forkCommunicationFds[1], "execvpe");
+#else
+            // XXX Check result
+            execve(exec_path, args, environment);
+            child_failed(forkCommunicationFds[1], "execve");
+#endif
+        } else {
+            // XXX Check result
+            execvp(args[0], args);
+            child_failed(forkCommunicationFds[1], "execvp");
+        }
+
+    default:
+        if ((flags & RUN_PROCESS_IN_NEW_GROUP) != 0) {
+            setpgid(pid, pid);
+        }
+        close(forkCommunicationFds[1]);
+        fcntl(forkCommunicationFds[0], F_SETFD, FD_CLOEXEC);
+
+        break;
+    }
+
+    // If the child process had a problem, then it will tell us via the
+    // forkCommunicationFds pipe. First we try to read what the problem
+    // was. Note that if none of these conditionals match then we fall
+    // through and just return pid.
+    char *fail_reason;
+    r = read(forkCommunicationFds[0], &fail_reason, sizeof(fail_reason));
+    if (r == -1) {
+        *failed_doing = "read pipe";
+        pid = -1;
+    }
+    else if (r == sizeof(fail_reason)) {
+        *failed_doing = fail_reason;
+
+        // Now we try to get the errno from the child
+        int err;
+        r = read(forkCommunicationFds[0], &err, sizeof(err));
+        if (r == -1) {
+            *failed_doing = "read pipe";
+        } else if (r != sizeof(err)) {
+            *failed_doing = "read pipe bad length";
+        } else {
+            // If we succeed then we set errno. It'll be saved and
+            // restored again below. Note that in any other case we'll
+            // get the errno of whatever else went wrong instead.
+            errno = err;
+        }
+
+        // We forked the child, but the child had a problem and stopped so it's
+        // our responsibility to reap here as nobody else can.
+        waitpid(pid, NULL, 0);
+
+        // No need to close stdin, et al. here as runInteractiveProcess will
+        // handle this. See #306.
+
+        pid = -1;
+    }
+    else if (r != 0) {
+        *failed_doing = "read pipe bad length";
+        pid = -1;
+    }
+
+    close(forkCommunicationFds[0]);
+
+    unblockUserSignals();
+    startTimer();
+
+    return pid;
+}
+
+#endif // HAVE_FORK
diff --git a/cbits/posix/posix_spawn.c b/cbits/posix/posix_spawn.c
new file mode 100644
--- /dev/null
+++ b/cbits/posix/posix_spawn.c
@@ -0,0 +1,261 @@
+// Necessary for POSIX_SPAWN_SETSID and posix_spawn_file_actions_addchdir_np under glibc.
+// Moreover this needs to appear before any glibc headers.
+#define _GNU_SOURCE
+
+#include "runProcess.h"
+#include "common.h"
+
+#include <unistd.h>
+#include <errno.h>
+
+#if defined(HAVE_SIGNAL_H)
+#include <signal.h>
+#include <fcntl.h>
+#endif
+
+#if !defined(USE_POSIX_SPAWN)
+ProcHandle
+do_spawn_posix (char *const args[],
+                char *workingDirectory, char **environment,
+                struct std_handle *stdInHdl,
+                struct std_handle *stdOutHdl,
+                struct std_handle *stdErrHdl,
+                gid_t *childGroup, uid_t *childUser,
+                int flags,
+                char **failed_doing)
+{
+    return -2;
+}
+
+#else
+
+#include <spawn.h>
+
+extern char **environ;
+
+static int
+setup_std_handle_spawn (int fd,
+                        struct std_handle *hdl,
+                        posix_spawn_file_actions_t *fa,
+                        char **failed_doing)
+{
+    switch (hdl->behavior) {
+    case STD_HANDLE_CLOSE:
+        // N.B. POSIX specifies that addclose() may result in spawnp() failing
+        // if the fd to-be-closed is already closed. Consequently, we must
+        // first open a file (e.g. /dev/null) and before attempting to close
+        // the fd. Fixes #251.
+        if (posix_spawn_file_actions_addopen(fa, fd, "/dev/null", O_RDONLY, 0) != 0) {
+            *failed_doing = "posix_spawn_file_actions_addopen";
+            return -1;
+        }
+        if (posix_spawn_file_actions_addclose(fa, fd) != 0) {
+            *failed_doing = "posix_spawn_file_actions_addclose";
+            return -1;
+        }
+        return 0;
+
+    case STD_HANDLE_USE_FD:
+        // N.B. POSIX specifies that dup2(x,x) should be a no-op, but
+        // naturally Apple ignores this and rather fails in posix_spawn on Big
+        // Sur.
+        if (hdl->use_fd != fd) {
+            if (posix_spawn_file_actions_adddup2(fa, hdl->use_fd, fd) != 0) {
+                *failed_doing = "posix_spawn_file_actions_adddup2";
+                return -1;
+            }
+       }
+        return 0;
+
+    case STD_HANDLE_USE_PIPE:
+        if (hdl->use_pipe.child_end != fd) {
+            if (posix_spawn_file_actions_adddup2(fa, hdl->use_pipe.child_end, fd) != 0) {
+                *failed_doing = "posix_spawn_file_actions_adddup2(child_end)";
+                return -1;
+            }
+            if (posix_spawn_file_actions_addclose(fa, hdl->use_pipe.child_end) != 0) {
+                *failed_doing = "posix_spawn_file_actions_addclose(child_end)";
+                return -1;
+            }
+        }
+        if (posix_spawn_file_actions_addclose(fa, hdl->use_pipe.parent_end) != 0) {
+            *failed_doing = "posix_spawn_file_actions_addclose(parent_end)";
+            return -1;
+        }
+        return 0;
+
+    default:
+	// N.B. this should be unreachable
+	// but some compilers apparently can't
+	// see this.
+        *failed_doing = "posix_spawn_file_actions_addclose(invalid behavior)";
+        return -1;
+    }
+}
+
+/* Try spawning with posix_spawn. Returns -1 if posix_spawn (or the particular
+ * requested configuration) is not supported.
+ */
+ProcHandle
+do_spawn_posix (char *const args[],
+                char *workingDirectory, char **environment,
+                struct std_handle *stdInHdl,
+                struct std_handle *stdOutHdl,
+                struct std_handle *stdErrHdl,
+                gid_t *childGroup, uid_t *childUser,
+                int flags,
+                char **failed_doing)
+{
+    // First do catch some cases that posix_spawn simply can't handle...
+    if (childGroup || childUser) {
+        return -2;
+    }
+    if ((flags & RUN_PROCESS_IN_CLOSE_FDS) != 0) {
+        // TODO: can this be efficiently supported?
+        return -2;
+    }
+
+    // Now the main act...
+    pid_t pid;
+    posix_spawn_file_actions_t fa;
+    posix_spawnattr_t sa;
+    int r;
+    ProcHandle ret;
+    short spawn_flags = 0;
+
+    r = posix_spawn_file_actions_init(&fa);
+    if (r != 0) {
+        *failed_doing = "posix_spawn_file_actions_init";
+        return -1;
+    }
+
+    r = posix_spawnattr_init(&sa);
+    if (r != 0) {
+        posix_spawn_file_actions_destroy(&fa);
+        *failed_doing = "posix_spawnattr_init";
+        return -1;
+    }
+
+    if (workingDirectory) {
+#if defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)
+#if defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP)
+        // N.B. in certain toolchain versions, apple will act as if symbols exist
+        // because the toolchain can be *used* for targets that have them.
+        // At runtime, however, they will be NULL. So, if both symbols are
+        // available, first check if the _np version *should* be available,
+        // if it is, add a runtime check whether the non-_np version is NULL
+        // and fallback to the _np version if it is
+        // See also: https://github.com/haskell/process/issues/356
+        if (posix_spawn_file_actions_addchdir == NULL) {
+          r = posix_spawn_file_actions_addchdir_np(&fa, workingDirectory);
+        } else {
+          r = posix_spawn_file_actions_addchdir(&fa, workingDirectory);
+        }
+#else
+        r = posix_spawn_file_actions_addchdir(&fa, workingDirectory);
+#endif
+        if (r != 0) {
+            *failed_doing = "posix_spawn_file_actions_addchdir";
+            goto fail;
+        }
+#elif defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP)
+        // N.B. this function is broken on macOS.
+        // See https://github.com/rust-lang/rust/pull/80537.
+        r = posix_spawn_file_actions_addchdir_np(&fa, workingDirectory);
+        if (r != 0) {
+            *failed_doing = "posix_spawn_file_actions_addchdir_np";
+            goto fail;
+        }
+#else
+        goto not_supported;
+#endif
+    }
+
+    if ((flags & RUN_PROCESS_NEW_SESSION) != 0) {
+#if defined(HAVE_POSIX_SPAWN_SETSID)
+        // N.B. POSIX_SPAWN_SETSID is only supported on macOS 10.15 and later,
+        // but an proper error is not returned in earlier versions.
+        // See https://bugs.python.org/issue37586.
+        if (posix_spawnattr_setflags(&sa, POSIX_SPAWN_SETSID) != 0) {
+            *failed_doing = "posix_spawnattr_setflags(POSIX_SPAWN_SETSID)";
+            goto fail;
+        }
+#elif defined(HAVE_POSIX_SPAWN_SETSID_NP)
+        if (posix_spawnattr_setflags(&sa, POSIX_SPAWN_SETSID_NP) != 0) {
+            *failed_doing = "posix_spawnattr_setflags(POSIX_SPAWN_SETSID_NP)";
+            goto fail;
+        }
+#else
+        goto not_supported;
+#endif
+    }
+
+    if ((flags & RUN_PROCESS_IN_NEW_GROUP) != 0) {
+#if defined(HAVE_POSIX_SPAWN_SETPGROUP)
+        spawn_flags |= POSIX_SPAWN_SETPGROUP;
+#else
+        goto not_supported;
+#endif
+    }
+
+    if (setup_std_handle_spawn(STDIN_FILENO,  stdInHdl,  &fa, failed_doing) != 0) {
+        goto fail;
+    }
+    if (setup_std_handle_spawn(STDOUT_FILENO, stdOutHdl, &fa, failed_doing) != 0) {
+        goto fail;
+    }
+    if (setup_std_handle_spawn(STDERR_FILENO, stdErrHdl, &fa, failed_doing) != 0) {
+        goto fail;
+    }
+
+    sigset_t ss;
+    if ((flags & RESET_INT_QUIT_HANDLERS) != 0) {
+        if (sigemptyset(&ss) == -1) {
+            *failed_doing = "sigemptyset";
+            goto fail;
+        }
+        if (sigaddset(&ss, SIGINT) == -1) {
+            *failed_doing = "sigaddset(SIGINT)";
+            goto fail;
+        }
+        if (sigaddset(&ss, SIGQUIT) == -1) {
+            *failed_doing = "sigaddset(SIGQUIT)";
+            goto fail;
+        }
+        if (posix_spawnattr_setsigdefault(&sa, &ss) != 0) {
+            *failed_doing = "posix_spawnattr_setsigdefault";
+            goto fail;
+        }
+        spawn_flags |= POSIX_SPAWN_SETSIGDEF;
+    }
+
+    if (posix_spawnattr_setflags(&sa, spawn_flags) != 0) {
+        *failed_doing = "posix_spawnattr_setflags";
+        goto fail;
+    }
+
+    r = posix_spawnp(&pid, args[0], &fa, &sa, args, environment ? environment : environ);
+    if (r != 0) {
+        errno = r; // posix_spawn doesn't necessarily set errno; see #227.
+        *failed_doing = "posix_spawnp";
+        goto fail;
+    } else {
+        ret = pid;
+        goto finish;
+    }
+
+not_supported:
+    ret = -2;
+    goto finish;
+
+fail:
+    ret = -1;
+    goto finish;
+
+finish:
+    posix_spawn_file_actions_destroy(&fa);
+    posix_spawnattr_destroy(&sa);
+    return ret;
+}
+
+#endif
diff --git a/cbits/posix/runProcess.c b/cbits/posix/runProcess.c
new file mode 100644
--- /dev/null
+++ b/cbits/posix/runProcess.c
@@ -0,0 +1,280 @@
+/* ----------------------------------------------------------------------------
+   (c) The University of Glasgow 2004-2020
+
+   Support for System.Process
+   ------------------------------------------------------------------------- */
+
+#include "runProcess.h"
+
+// Callers are stubbed out on wasm32: runInteractiveProcess (System/Process/Posix.hs),
+// terminateProcess, getProcessExitCode, waitForProcess (System/Process.hs).
+#if !defined(wasm32_HOST_ARCH)
+
+#include "common.h"
+
+#include <unistd.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#if defined(HAVE_SIGNAL_H)
+#include <signal.h>
+#endif
+
+int
+get_max_fd()
+{
+    static int cache = 0;
+    if (cache == 0) {
+#if HAVE_SYSCONF
+        cache = sysconf(_SC_OPEN_MAX);
+        if (cache == -1) {
+            cache = 256;
+        }
+#else
+        cache = 256;
+#endif
+    }
+    return cache;
+}
+
+// If a process was terminated by a signal, the exit status we return
+// via the System.Process API is (-signum). This encoding avoids collision with
+// normal process termination status codes. See also #7229.
+#define TERMSIG_EXITSTATUS(s) (-(WTERMSIG(s)))
+
+/*
+ * Spawn a new process. We first try posix_spawn but since this isn't supported
+ * on all platforms we fall back to fork/exec in some cases on some platforms.
+ */
+static ProcHandle
+do_spawn (char *const args[],
+          char *workingDirectory, char **environment,
+          struct std_handle *stdInHdl,
+          struct std_handle *stdOutHdl,
+          struct std_handle *stdErrHdl,
+          gid_t *childGroup, uid_t *childUser,
+          int flags,
+          char **failed_doing)
+{
+    ProcHandle r;
+    r = do_spawn_posix(args,
+                       workingDirectory, environment,
+                       stdInHdl, stdOutHdl, stdErrHdl,
+                       childGroup, childUser,
+                       flags,
+                       failed_doing);
+    if (r == -2) {
+        // configuration not supported by posix_spawn, fall back to fork/exec
+    } else {
+        return r;
+    }
+
+#if defined(HAVE_FORK)
+    r = do_spawn_fork(args,
+                      workingDirectory, environment,
+                      stdInHdl, stdOutHdl, stdErrHdl,
+                      childGroup, childUser,
+                      flags,
+                      failed_doing);
+    return r;
+#else
+    *failed_doing = "fork";
+    return -1;
+#endif
+
+}
+
+enum pipe_direction {
+    CHILD_READS, CHILD_WRITES
+};
+
+/* Initialize a std_handle_behavior from a "pseudo-fd":
+ *   - fd == -1 means create a pipe
+ *   - fd == -2 means close the handle
+ *   - otherwise use fd
+ * Returns 0 on success, -1 otherwise.
+ */
+static int
+init_std_handle(int fd, enum pipe_direction direction,
+                         /* out */ struct std_handle *hdl,
+                         char **failed_doing)
+{
+    switch (fd) {
+    case -1: {
+        int pipe_fds[2];
+        int r = pipe(pipe_fds);
+        if (r == -1) {
+            *failed_doing = "pipe";
+            return -1;
+        }
+
+        int child_end  = direction == CHILD_READS ? 0 : 1;
+        int parent_end = direction == CHILD_READS ? 1 : 0;
+        *hdl = (struct std_handle) {
+            .behavior = STD_HANDLE_USE_PIPE,
+            .use_pipe = { .child_end = pipe_fds[child_end], .parent_end = pipe_fds[parent_end] }
+        };
+        break;
+    }
+    case -2:
+        *hdl = (struct std_handle) {
+            .behavior = STD_HANDLE_CLOSE
+        };
+        break;
+    default:
+        *hdl = (struct std_handle) {
+            .behavior = STD_HANDLE_USE_FD,
+            .use_fd = fd
+        };
+        break;
+    }
+    return 0;
+}
+
+ProcHandle
+runInteractiveProcess (char *const args[],
+                       char *workingDirectory, char **environment,
+                       // handles to use for the standard handles. -1 indicates
+                       // create pipe, -2 indicates close.
+                       int fdStdIn, int fdStdOut, int fdStdErr,
+                       // output arguments to return created pipe handle to caller
+                       int *pfdStdInput, int *pfdStdOutput, int *pfdStdError,
+                       gid_t *childGroup, uid_t *childUser,
+                       int flags,
+                       char **failed_doing)
+{
+    struct std_handle stdInHdl, stdOutHdl, stdErrHdl;
+    ProcHandle r;
+
+    // A bit of paranoia to ensure that we catch if we fail to set this on
+    // failure.
+    *failed_doing = NULL;
+
+    // Ordering matters here, see below Note [Ordering of handle closing].
+    if (init_std_handle(fdStdIn, CHILD_READS, &stdInHdl, failed_doing) != 0) {
+        goto fail;
+    }
+
+    if (init_std_handle(fdStdOut, CHILD_WRITES, &stdOutHdl, failed_doing) != 0) {
+        goto fail;
+    }
+
+    if (init_std_handle(fdStdErr, CHILD_WRITES, &stdErrHdl, failed_doing) != 0) {
+        goto fail;
+    }
+
+    r = do_spawn(args,
+                 workingDirectory, environment,
+                 &stdInHdl, &stdOutHdl, &stdErrHdl,
+                 childGroup, childUser,
+                 flags,
+                 failed_doing);
+    if (r == -1) {
+        goto fail;
+    }
+
+    // Close the remote ends of any pipes we created.
+#define FINALISE_STD_HANDLE(hdl, pfd) \
+    if (hdl.behavior == STD_HANDLE_USE_PIPE) { \
+        close(hdl.use_pipe.child_end); \
+        fcntl(hdl.use_pipe.parent_end, F_SETFD, FD_CLOEXEC); \
+        *pfd  = hdl.use_pipe.parent_end; \
+    }
+
+    FINALISE_STD_HANDLE(stdInHdl,  pfdStdInput);
+    FINALISE_STD_HANDLE(stdOutHdl, pfdStdOutput);
+    FINALISE_STD_HANDLE(stdErrHdl, pfdStdError);
+#undef FINALISE_STD_HANDLE
+
+    return r;
+
+fail:
+#define CLOSE_PIPE(hdl) \
+    if (hdl.behavior == STD_HANDLE_USE_PIPE) { \
+        close(hdl.use_pipe.child_end); \
+        close(hdl.use_pipe.parent_end); \
+    }
+
+    CLOSE_PIPE(stdInHdl);
+    CLOSE_PIPE(stdOutHdl);
+    CLOSE_PIPE(stdErrHdl);
+#undef CLOSE_PIPE
+
+    return -1;
+}
+
+int
+terminateProcess (ProcHandle handle)
+{
+    return (kill(handle, SIGTERM) == 0);
+}
+
+int
+getProcessExitCode (ProcHandle handle, int *pExitCode)
+{
+    int wstat, res;
+
+    *pExitCode = 0;
+
+    if ((res = waitpid(handle, &wstat, WNOHANG)) > 0) {
+        if (WIFEXITED(wstat)) {
+            *pExitCode = WEXITSTATUS(wstat);
+            return 1;
+        } else {
+            if (WIFSIGNALED(wstat))
+            {
+                *pExitCode = TERMSIG_EXITSTATUS(wstat);
+                return 1;
+            }
+            else
+            {
+                /* This should never happen */
+            }
+        }
+    }
+
+    if (res == 0) return 0;
+
+    if (errno == ECHILD)
+    {
+        *pExitCode = 0;
+        return 1;
+    }
+
+    return -1;
+}
+
+int
+waitForProcess (ProcHandle handle, int *pret)
+{
+    int wstat;
+
+    if (waitpid(handle, &wstat, 0) < 0)
+    {
+        return -1;
+    }
+
+    if (WIFEXITED(wstat)) {
+        *pret = WEXITSTATUS(wstat);
+        return 0;
+    }
+    else {
+        if (WIFSIGNALED(wstat))
+        {
+            *pret = TERMSIG_EXITSTATUS(wstat);
+            return 0;
+        }
+        else
+        {
+            /* This should never happen */
+        }
+    }
+
+    return -1;
+}
+
+#endif // !wasm32_HOST_ARCH
diff --git a/cbits/runProcess.c b/cbits/runProcess.c
deleted file mode 100644
--- a/cbits/runProcess.c
+++ /dev/null
@@ -1,656 +0,0 @@
-/* ----------------------------------------------------------------------------
-   (c) The University of Glasgow 2004
-
-   Support for System.Process
-   ------------------------------------------------------------------------- */
-
-#if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
-#define UNICODE
-#endif
-
-/* XXX This is a nasty hack; should put everything necessary in this package */
-#include "HsBase.h"
-#include "Rts.h"
-
-#include "runProcess.h"
-
-#if !(defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32))
-
-#include "execvpe.h"
-
-/* ----------------------------------------------------------------------------
-   UNIX versions
-   ------------------------------------------------------------------------- */
-
-// If a process was terminated by a signal, the exit status we return
-// via the System.Process API is (-signum). This encoding avoids collision with
-// normal process termination status codes. See also #7229.
-#define TERMSIG_EXITSTATUS(s) (-(WTERMSIG(s)))
-
-static long max_fd = 0;
-
-// Rts internal API, not exposed in a public header file:
-extern void blockUserSignals(void);
-extern void unblockUserSignals(void);
-
-// See #1593.  The convention for the exit code when
-// exec() fails seems to be 127 (gleened from C's
-// system()), but there's no equivalent convention for
-// chdir(), so I'm picking 126 --SimonM.
-#define forkChdirFailed 126
-#define forkExecFailed  127
-
-__attribute__((__noreturn__))
-static void childFailed(int pipe, int failCode) {
-    int err;
-    ssize_t unused __attribute__((unused));
-
-    err = errno;
-    unused = write(pipe, &failCode, sizeof(failCode));
-    unused = write(pipe, &err,      sizeof(err));
-    // As a fallback, exit with the failCode
-    _exit(failCode);
-}
-
-ProcHandle
-runInteractiveProcess (char *const args[],
-                       char *workingDirectory, char **environment,
-                       int fdStdIn, int fdStdOut, int fdStdErr,
-                       int *pfdStdInput, int *pfdStdOutput, int *pfdStdError,
-                       int reset_int_quit_handlers,
-                       int flags,
-                       char **failed_doing)
-{
-    int close_fds = ((flags & RUN_PROCESS_IN_CLOSE_FDS) != 0);
-    int pid;
-    int fdStdInput[2], fdStdOutput[2], fdStdError[2];
-    int forkCommunicationFds[2];
-    int r;
-    int failCode, err;
-
-    // Ordering matters here, see below [Note #431].
-    if (fdStdIn == -1) {
-        r = pipe(fdStdInput);
-        if (r == -1) {
-            *failed_doing = "runInteractiveProcess: pipe";
-            return -1;
-        }
-    }
-    if (fdStdOut == -1) {
-        r = pipe(fdStdOutput);
-        if (r == -1) {
-            *failed_doing = "runInteractiveProcess: pipe";
-            return -1;
-        }
-    }
-    if (fdStdErr == -1) {
-        r = pipe(fdStdError);
-        if (r == -1) {
-            *failed_doing = "runInteractiveProcess: pipe";
-            return -1;
-        }
-    }
-
-    r = pipe(forkCommunicationFds);
-    if (r == -1) {
-        *failed_doing = "runInteractiveProcess: pipe";
-        return -1;
-    }
-
-    // Block signals with Haskell handlers.  The danger here is that
-    // with the threaded RTS, a signal arrives in the child process,
-    // the RTS writes the signal information into the pipe (which is
-    // shared between parent and child), and the parent behaves as if
-    // the signal had been raised.
-    blockUserSignals();
-
-    // See #4074.  Sometimes fork() gets interrupted by the timer
-    // signal and keeps restarting indefinitely.
-    stopTimer();
-
-    switch(pid = myfork())
-    {
-    case -1:
-        unblockUserSignals();
-        startTimer();
-        if (fdStdIn == -1) {
-            close(fdStdInput[0]);
-            close(fdStdInput[1]);
-        }
-        if (fdStdOut == -1) {
-            close(fdStdOutput[0]);
-            close(fdStdOutput[1]);
-        }
-        if (fdStdErr == -1) {
-            close(fdStdError[0]);
-            close(fdStdError[1]);
-        }
-        close(forkCommunicationFds[0]);
-        close(forkCommunicationFds[1]);
-        *failed_doing = "fork";
-        return -1;
-
-    case 0:
-        // WARNING! We may now be in the child of vfork(), and any
-        // memory we modify below may also be seen in the parent
-        // process.
-
-        close(forkCommunicationFds[0]);
-        fcntl(forkCommunicationFds[1], F_SETFD, FD_CLOEXEC);
-
-        if ((flags & RUN_PROCESS_NEW_SESSION) != 0) {
-            setsid();
-        }
-        if ((flags & RUN_PROCESS_IN_NEW_GROUP) != 0) {
-            setpgid(0, 0);
-        }
-
-        unblockUserSignals();
-
-        if (workingDirectory) {
-            if (chdir (workingDirectory) < 0) {
-                childFailed(forkCommunicationFds[1], forkChdirFailed);
-            }
-        }
-
-        // [Note #431]: Ordering matters here.  If any of the FDs
-        // 0,1,2 were initially closed, then our pipes may have used
-        // these FDs.  So when we dup2 the pipe FDs down to 0,1,2, we
-        // must do it in that order, otherwise we could overwrite an
-        // FD that we need later.
-
-        if (fdStdIn == -1) {
-            if (fdStdInput[0] != STDIN_FILENO) {
-                dup2 (fdStdInput[0], STDIN_FILENO);
-                close(fdStdInput[0]);
-            }
-            close(fdStdInput[1]);
-        } else if (fdStdIn == -2) {
-            close(STDIN_FILENO);
-        } else {
-            dup2(fdStdIn,  STDIN_FILENO);
-        }
-
-        if (fdStdOut == -1) {
-            if (fdStdOutput[1] != STDOUT_FILENO) {
-                dup2 (fdStdOutput[1], STDOUT_FILENO);
-                close(fdStdOutput[1]);
-            }
-            close(fdStdOutput[0]);
-        } else if (fdStdOut == -2) {
-            close(STDOUT_FILENO);
-        } else {
-            dup2(fdStdOut,  STDOUT_FILENO);
-        }
-
-        if (fdStdErr == -1) {
-            if (fdStdError[1] != STDERR_FILENO) {
-                dup2 (fdStdError[1], STDERR_FILENO);
-                close(fdStdError[1]);
-            }
-            close(fdStdError[0]);
-        } else if (fdStdErr == -2) {
-            close(STDERR_FILENO);
-        } else {
-            dup2(fdStdErr,  STDERR_FILENO);
-        }
-
-        if (close_fds) {
-            int i;
-            if (max_fd == 0) {
-#if HAVE_SYSCONF
-                max_fd = sysconf(_SC_OPEN_MAX);
-                if (max_fd == -1) {
-                    max_fd = 256;
-                }
-#else
-                max_fd = 256;
-#endif
-            }
-            // XXX Not the pipe
-            for (i = 3; i < max_fd; i++) {
-		if (i != forkCommunicationFds[1]) {
-		    close(i);
-		}
-            }
-        }
-
-        /* Reset the SIGINT/SIGQUIT signal handlers in the child, if requested
-         */
-        if (reset_int_quit_handlers) {
-            struct sigaction dfl;
-            (void)sigemptyset(&dfl.sa_mask);
-            dfl.sa_flags = 0;
-            dfl.sa_handler = SIG_DFL;
-            (void)sigaction(SIGINT,  &dfl, NULL);
-            (void)sigaction(SIGQUIT, &dfl, NULL);
-        }
-
-        /* the child */
-        if (environment) {
-            // XXX Check result
-            execvpe(args[0], args, environment);
-        } else {
-            // XXX Check result
-            execvp(args[0], args);
-        }
-
-        childFailed(forkCommunicationFds[1], forkExecFailed);
-
-    default:
-        if ((flags & RUN_PROCESS_IN_NEW_GROUP) != 0) {
-            setpgid(pid, pid);
-        }
-        if (fdStdIn  == -1) {
-            close(fdStdInput[0]);
-            fcntl(fdStdInput[1], F_SETFD, FD_CLOEXEC);
-            *pfdStdInput  = fdStdInput[1];
-        }
-        if (fdStdOut == -1) {
-            close(fdStdOutput[1]);
-            fcntl(fdStdOutput[0], F_SETFD, FD_CLOEXEC);
-            *pfdStdOutput = fdStdOutput[0];
-        }
-        if (fdStdErr == -1) {
-            close(fdStdError[1]);
-            fcntl(fdStdError[0], F_SETFD, FD_CLOEXEC);
-            *pfdStdError  = fdStdError[0];
-        }
-        close(forkCommunicationFds[1]);
-        fcntl(forkCommunicationFds[0], F_SETFD, FD_CLOEXEC);
-
-        break;
-    }
-
-    // If the child process had a problem, then it will tell us via the
-    // forkCommunicationFds pipe. First we try to read what the problem
-    // was. Note that if none of these conditionals match then we fall
-    // through and just return pid.
-    r = read(forkCommunicationFds[0], &failCode, sizeof(failCode));
-    if (r == -1) {
-        *failed_doing = "runInteractiveProcess: read pipe";
-        pid = -1;
-    }
-    else if (r == sizeof(failCode)) {
-        // This is the case where we successfully managed to read
-        // the problem
-        switch (failCode) {
-        case forkChdirFailed:
-            *failed_doing = "runInteractiveProcess: chdir";
-            break;
-        case forkExecFailed:
-            *failed_doing = "runInteractiveProcess: exec";
-            break;
-        default:
-            *failed_doing = "runInteractiveProcess: unknown";
-            break;
-        }
-        // Now we try to get the errno from the child
-        r = read(forkCommunicationFds[0], &err, sizeof(err));
-        if (r == -1) {
-            *failed_doing = "runInteractiveProcess: read pipe";
-        }
-        else if (r != sizeof(failCode)) {
-            *failed_doing = "runInteractiveProcess: read pipe bad length";
-        }
-        else {
-            // If we succeed then we set errno. It'll be saved and
-            // restored again below. Note that in any other case we'll
-            // get the errno of whatever else went wrong instead.
-            errno = err;
-        }
-
-        // We forked the child, but the child had a problem and stopped so it's
-        // our responsibility to reap here as nobody else can.
-        waitpid(pid, NULL, 0);
-
-        pid = -1;
-    }
-    else if (r != 0) {
-        *failed_doing = "runInteractiveProcess: read pipe bad length";
-        pid = -1;
-    }
-
-    if (pid == -1) {
-        err = errno;
-    }
-
-    close(forkCommunicationFds[0]);
-
-    unblockUserSignals();
-    startTimer();
-
-    if (pid == -1) {
-        errno = err;
-    }
-
-    return pid;
-}
-
-int
-terminateProcess (ProcHandle handle)
-{
-    return (kill(handle, SIGTERM) == 0);
-}
-
-int
-getProcessExitCode (ProcHandle handle, int *pExitCode)
-{
-    int wstat, res;
-
-    *pExitCode = 0;
-
-    if ((res = waitpid(handle, &wstat, WNOHANG)) > 0)
-    {
-        if (WIFEXITED(wstat))
-        {
-            *pExitCode = WEXITSTATUS(wstat);
-            return 1;
-        }
-        else
-            if (WIFSIGNALED(wstat))
-            {
-                *pExitCode = TERMSIG_EXITSTATUS(wstat);
-                return 1;
-            }
-            else
-            {
-                /* This should never happen */
-            }
-    }
-
-    if (res == 0) return 0;
-
-    if (errno == ECHILD)
-    {
-        *pExitCode = 0;
-        return 1;
-    }
-
-    return -1;
-}
-
-int waitForProcess (ProcHandle handle, int *pret)
-{
-    int wstat;
-
-    if (waitpid(handle, &wstat, 0) < 0)
-    {
-        return -1;
-    }
-
-    if (WIFEXITED(wstat)) {
-        *pret = WEXITSTATUS(wstat);
-        return 0;
-    }
-    else {
-        if (WIFSIGNALED(wstat))
-        {
-            *pret = TERMSIG_EXITSTATUS(wstat);
-            return 0;
-        }
-        else
-        {
-            /* This should never happen */
-        }
-    }
-
-    return -1;
-}
-
-#else
-/* ----------------------------------------------------------------------------
-   Win32 versions
-   ------------------------------------------------------------------------- */
-
-/* -------------------- WINDOWS VERSION --------------------- */
-
-/*
- * Function: mkAnonPipe
- *
- * Purpose:  create an anonymous pipe with read and write ends being
- *           optionally (non-)inheritable.
- */
-static BOOL
-mkAnonPipe (HANDLE* pHandleIn, BOOL isInheritableIn,
-            HANDLE* pHandleOut, BOOL isInheritableOut)
-{
-    HANDLE hTemporaryIn  = NULL;
-    HANDLE hTemporaryOut = NULL;
-
-    /* Create the anon pipe with both ends inheritable */
-    if (!CreatePipe(&hTemporaryIn, &hTemporaryOut, NULL, 0))
-    {
-        maperrno();
-        *pHandleIn  = NULL;
-        *pHandleOut = NULL;
-        return FALSE;
-    }
-
-    if (isInheritableIn) {
-        // SetHandleInformation requires at least Win2k
-        if (!SetHandleInformation(hTemporaryIn,
-                                  HANDLE_FLAG_INHERIT,
-                                  HANDLE_FLAG_INHERIT))
-        {
-            maperrno();
-            *pHandleIn  = NULL;
-            *pHandleOut = NULL;
-            CloseHandle(hTemporaryIn);
-            CloseHandle(hTemporaryOut);
-            return FALSE;
-        }
-    }
-    *pHandleIn = hTemporaryIn;
-
-    if (isInheritableOut) {
-        if (!SetHandleInformation(hTemporaryOut,
-                                  HANDLE_FLAG_INHERIT,
-                                  HANDLE_FLAG_INHERIT))
-        {
-            maperrno();
-            *pHandleIn  = NULL;
-            *pHandleOut = NULL;
-            CloseHandle(hTemporaryIn);
-            CloseHandle(hTemporaryOut);
-            return FALSE;
-        }
-    }
-    *pHandleOut = hTemporaryOut;
-
-    return TRUE;
-}
-
-ProcHandle
-runInteractiveProcess (wchar_t *cmd, wchar_t *workingDirectory,
-                       wchar_t *environment,
-                       int fdStdIn, int fdStdOut, int fdStdErr,
-                       int *pfdStdInput, int *pfdStdOutput, int *pfdStdError,
-                       int flags)
-{
-    STARTUPINFO sInfo;
-    PROCESS_INFORMATION pInfo;
-    HANDLE hStdInputRead   = INVALID_HANDLE_VALUE;
-    HANDLE hStdInputWrite  = INVALID_HANDLE_VALUE;
-    HANDLE hStdOutputRead  = INVALID_HANDLE_VALUE;
-    HANDLE hStdOutputWrite = INVALID_HANDLE_VALUE;
-    HANDLE hStdErrorRead   = INVALID_HANDLE_VALUE;
-    HANDLE hStdErrorWrite  = INVALID_HANDLE_VALUE;
-    BOOL close_fds = ((flags & RUN_PROCESS_IN_CLOSE_FDS) != 0);
-    // We always pass a wide environment block, so we MUST set this flag
-    DWORD dwFlags = CREATE_UNICODE_ENVIRONMENT;
-    BOOL status;
-    BOOL inherit;
-
-    ZeroMemory(&sInfo, sizeof(sInfo));
-    sInfo.cb = sizeof(sInfo);
-    sInfo.dwFlags = STARTF_USESTDHANDLES;
-
-    if (fdStdIn == -1) {
-        if (!mkAnonPipe(&hStdInputRead,  TRUE, &hStdInputWrite,  FALSE))
-            goto cleanup_err;
-        sInfo.hStdInput = hStdInputRead;
-    } else if (fdStdIn == -2) {
-        sInfo.hStdInput = NULL;
-    } else if (fdStdIn == 0) {
-        // Don't duplicate stdin, as console handles cannot be
-        // duplicated and inherited. urg.
-        sInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
-    } else {
-        // The handle might not be inheritable, so duplicate it
-        status = DuplicateHandle(GetCurrentProcess(),
-                                 (HANDLE) _get_osfhandle(fdStdIn),
-                                 GetCurrentProcess(), &hStdInputRead,
-                                 0,
-                                 TRUE, /* inheritable */
-                                 DUPLICATE_SAME_ACCESS);
-        if (!status) goto cleanup_err;
-        sInfo.hStdInput = hStdInputRead;
-    }
-
-    if (fdStdOut == -1) {
-        if (!mkAnonPipe(&hStdOutputRead,  FALSE, &hStdOutputWrite,  TRUE))
-            goto cleanup_err;
-        sInfo.hStdOutput = hStdOutputWrite;
-    } else if (fdStdOut == -2) {
-        sInfo.hStdOutput = NULL;
-    } else if (fdStdOut == 1) {
-        // Don't duplicate stdout, as console handles cannot be
-        // duplicated and inherited. urg.
-        sInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
-    } else {
-        // The handle might not be inheritable, so duplicate it
-        status = DuplicateHandle(GetCurrentProcess(),
-                                 (HANDLE) _get_osfhandle(fdStdOut),
-                                 GetCurrentProcess(), &hStdOutputWrite,
-                                 0,
-                                 TRUE, /* inheritable */
-                                 DUPLICATE_SAME_ACCESS);
-        if (!status) goto cleanup_err;
-        sInfo.hStdOutput = hStdOutputWrite;
-    }
-
-    if (fdStdErr == -1) {
-        if (!mkAnonPipe(&hStdErrorRead,  TRUE, &hStdErrorWrite,  TRUE))
-            goto cleanup_err;
-        sInfo.hStdError = hStdErrorWrite;
-    } else if (fdStdErr == -2) {
-        sInfo.hStdError = NULL;
-    } else if (fdStdErr == 2) {
-        // Don't duplicate stderr, as console handles cannot be
-        // duplicated and inherited. urg.
-        sInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
-    } else {
-        /* The handle might not be inheritable, so duplicate it */
-        status = DuplicateHandle(GetCurrentProcess(),
-                                 (HANDLE) _get_osfhandle(fdStdErr),
-                                 GetCurrentProcess(), &hStdErrorWrite,
-                                 0,
-                                 TRUE, /* inheritable */
-                                 DUPLICATE_SAME_ACCESS);
-        if (!status) goto cleanup_err;
-        sInfo.hStdError = hStdErrorWrite;
-    }
-
-    if (sInfo.hStdInput  != GetStdHandle(STD_INPUT_HANDLE)  &&
-        sInfo.hStdOutput != GetStdHandle(STD_OUTPUT_HANDLE) &&
-        sInfo.hStdError  != GetStdHandle(STD_ERROR_HANDLE)  &&
-        (flags & RUN_PROCESS_IN_NEW_GROUP) == 0)
-            dwFlags |= CREATE_NO_WINDOW;   // Run without console window only when both output and error are redirected
-
-    // See #3231
-    if (close_fds && fdStdIn == 0 && fdStdOut == 1 && fdStdErr == 2) {
-        inherit = FALSE;
-    } else {
-        inherit = TRUE;
-    }
-
-    if ((flags & RUN_PROCESS_IN_NEW_GROUP) != 0) {
-        dwFlags |= CREATE_NEW_PROCESS_GROUP;
-    }
-    if ((flags & RUN_PROCESS_DETACHED) != 0) {
-        dwFlags |= DETACHED_PROCESS;
-    }
-    if ((flags & RUN_PROCESS_NEW_CONSOLE) != 0) {
-        dwFlags |= CREATE_NEW_CONSOLE;
-    }
-
-    if (!CreateProcess(NULL, cmd, NULL, NULL, inherit, dwFlags, environment, workingDirectory, &sInfo, &pInfo))
-    {
-            goto cleanup_err;
-    }
-    CloseHandle(pInfo.hThread);
-
-    // Close the ends of the pipes that were inherited by the
-    // child process.  This is important, otherwise we won't see
-    // EOF on these pipes when the child process exits.
-    if (hStdInputRead   != INVALID_HANDLE_VALUE) CloseHandle(hStdInputRead);
-    if (hStdOutputWrite != INVALID_HANDLE_VALUE) CloseHandle(hStdOutputWrite);
-    if (hStdErrorWrite  != INVALID_HANDLE_VALUE) CloseHandle(hStdErrorWrite);
-
-    *pfdStdInput  = _open_osfhandle((intptr_t) hStdInputWrite, _O_WRONLY);
-    *pfdStdOutput = _open_osfhandle((intptr_t) hStdOutputRead, _O_RDONLY);
-    *pfdStdError  = _open_osfhandle((intptr_t) hStdErrorRead,  _O_RDONLY);
-
-    return pInfo.hProcess;
-
-cleanup_err:
-    if (hStdInputRead   != INVALID_HANDLE_VALUE) CloseHandle(hStdInputRead);
-    if (hStdInputWrite  != INVALID_HANDLE_VALUE) CloseHandle(hStdInputWrite);
-    if (hStdOutputRead  != INVALID_HANDLE_VALUE) CloseHandle(hStdOutputRead);
-    if (hStdOutputWrite != INVALID_HANDLE_VALUE) CloseHandle(hStdOutputWrite);
-    if (hStdErrorRead   != INVALID_HANDLE_VALUE) CloseHandle(hStdErrorRead);
-    if (hStdErrorWrite  != INVALID_HANDLE_VALUE) CloseHandle(hStdErrorWrite);
-    maperrno();
-    return NULL;
-}
-
-int
-terminateProcess (ProcHandle handle)
-{
-    if (!TerminateProcess((HANDLE) handle, 1)) {
-        maperrno();
-        return -1;
-    }
-    return 0;
-}
-
-int
-getProcessExitCode (ProcHandle handle, int *pExitCode)
-{
-    *pExitCode = 0;
-
-    if (WaitForSingleObject((HANDLE) handle, 1) == WAIT_OBJECT_0)
-    {
-        if (GetExitCodeProcess((HANDLE) handle, (DWORD *) pExitCode) == 0)
-        {
-            maperrno();
-            return -1;
-        }
-        return 1;
-    }
-
-    return 0;
-}
-
-int
-waitForProcess (ProcHandle handle, int *pret)
-{
-    DWORD retCode;
-
-    if (WaitForSingleObject((HANDLE) handle, INFINITE) == WAIT_OBJECT_0)
-    {
-        if (GetExitCodeProcess((HANDLE) handle, &retCode) == 0)
-        {
-            maperrno();
-            return -1;
-        }
-        *pret = retCode;
-        return 0;
-    }
-
-    maperrno();
-    return -1;
-}
-
-#endif /* Win32 */
diff --git a/cbits/win32/runProcess.c b/cbits/win32/runProcess.c
new file mode 100644
--- /dev/null
+++ b/cbits/win32/runProcess.c
@@ -0,0 +1,666 @@
+/* ----------------------------------------------------------------------------
+   (c) The University of Glasgow 2004-2022
+
+   Support for System.Process
+   ------------------------------------------------------------------------- */
+
+#define UNICODE
+
+/* XXX This is a nasty hack; should put everything necessary in this package */
+#include "HsBase.h"
+#include "Rts.h"
+
+#include "runProcess.h"
+
+#include <assert.h>
+#include <windows.h>
+#include <io.h>
+#include <objbase.h>
+#include <wchar.h>
+
+/* ----------------------------------------------------------------------------
+   Win32 versions
+   ------------------------------------------------------------------------- */
+
+/* -------------------- WINDOWS VERSION --------------------- */
+
+/*
+ * Function: mkAnonPipe
+ *
+ * Purpose:  create an anonymous pipe with read and write ends being
+ *           optionally (non-)inheritable.
+ */
+static BOOL
+mkAnonPipe (HANDLE* pHandleIn, BOOL isInheritableIn,
+            HANDLE* pHandleOut, BOOL isInheritableOut)
+{
+    HANDLE hTemporaryIn  = NULL;
+    HANDLE hTemporaryOut = NULL;
+
+    /* Create the anon pipe with both ends inheritable */
+    if (!CreatePipe(&hTemporaryIn, &hTemporaryOut, NULL, 0))
+    {
+        maperrno();
+        *pHandleIn  = NULL;
+        *pHandleOut = NULL;
+        return FALSE;
+    }
+
+    if (isInheritableIn) {
+        // SetHandleInformation requires at least Win2k
+        if (!SetHandleInformation(hTemporaryIn,
+                                  HANDLE_FLAG_INHERIT,
+                                  HANDLE_FLAG_INHERIT))
+        {
+            maperrno();
+            *pHandleIn  = NULL;
+            *pHandleOut = NULL;
+            CloseHandle(hTemporaryIn);
+            CloseHandle(hTemporaryOut);
+            return FALSE;
+        }
+    }
+    *pHandleIn = hTemporaryIn;
+
+    if (isInheritableOut) {
+        if (!SetHandleInformation(hTemporaryOut,
+                                  HANDLE_FLAG_INHERIT,
+                                  HANDLE_FLAG_INHERIT))
+        {
+            maperrno();
+            *pHandleIn  = NULL;
+            *pHandleOut = NULL;
+            CloseHandle(hTemporaryIn);
+            CloseHandle(hTemporaryOut);
+            return FALSE;
+        }
+    }
+    *pHandleOut = hTemporaryOut;
+
+    return TRUE;
+}
+
+/*
+ * Function: mkNamedPipe
+ *
+ * Purpose:  create an named pipe with read and write ends being
+ *           optionally (non-)inheritable. Named pipes can be read
+ *           asynchronously while anonymous pipes require blocking calls.
+ */
+BOOL
+mkNamedPipe (HANDLE* pHandleIn, BOOL isInheritableIn, BOOL isOverlappedIn,
+             HANDLE* pHandleOut, BOOL isInheritableOut, BOOL isOverlappedOut)
+{
+    HANDLE hTemporaryIn  = INVALID_HANDLE_VALUE;
+    HANDLE hTemporaryOut = INVALID_HANDLE_VALUE;
+    RPC_WSTR guidStr = NULL;
+    GUID guid;
+
+    /* First we create a new GUID to make the name of the pipe unique. Since
+       GUID are guaranteed to be unique system wide we don't need to retry.  */
+    ZeroMemory (&guid, sizeof (guid));
+    if (CoCreateGuid (&guid) != S_OK)
+        goto fail;
+
+    if (UuidToStringW ((UUID*)&guid, &guidStr) != S_OK)
+        goto fail;
+
+    /* Now we create the pipe name.  */
+    wchar_t pipeName[MAX_PATH];
+    if (-1 == swprintf_s (&pipeName[0],  MAX_PATH, L"\\\\.\\pipe\\haskell:process:%ls\n",  guidStr))
+        goto fail;
+
+    const int buffer_size = 8 * 1024;
+
+    RpcStringFreeW (&guidStr);
+
+    SECURITY_ATTRIBUTES secAttr;
+    ZeroMemory (&secAttr, sizeof(secAttr));
+    secAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+    secAttr.lpSecurityDescriptor = NULL;
+    secAttr.bInheritHandle = isInheritableIn;
+
+    /* Create one end of the pipe. Named pipes are a bit less secure than
+       anonymous pipes.  Because of this we restrict the pipe's access to only
+       one client and also only the local host.  This means after we create the
+       other end of the pipe it should be as secure as an anonymous pipe.
+
+       "When you operate on named pipes, you have a choice of opening them in
+       PIPE_WAIT mode or PIPE_NOWAIT mode. When you read from a PIPE_WAIT pipe,
+       the read blocks until data becomes available in the pipe. When you read
+       from a PIPE_NOWAIT pipe, then the read completes immediately even if
+       there is no data in the pipe. But how is this different from a PIPE_WAIT
+       pipe opened in asynchronous mode by passing FILE_FLAG_OVERLAPPED? The
+       difference is in when the I/O is deemed to have completed. When you issue
+       an overlapped read against a PIPE_WAIT pipe, the call to Read­File returns
+       immediately, but the completion actions do not occur until there is data
+       available in the pipe. (Completion actions are things like setting the
+       event, running the completion routine, or queueing a completion to an I/O
+       completion port.) On the other hand, when you issue a read against a
+       PIPE_NOWAIT pipe, the call to Read­File returns immediately with
+       completion—if the pipe is empty, the read completes with a read of zero
+       bytes and the error ERROR_NO_DATA."[0]
+
+       [0] https://devblogs.microsoft.com/oldnewthing/20110114-00/?p=11753  */
+    DWORD inAttr = isOverlappedIn ? FILE_FLAG_OVERLAPPED : 0;
+    hTemporaryIn
+      = CreateNamedPipeW (pipeName,
+                          PIPE_ACCESS_INBOUND | inAttr | FILE_FLAG_FIRST_PIPE_INSTANCE,
+                          PIPE_TYPE_MESSAGE | PIPE_REJECT_REMOTE_CLIENTS | PIPE_READMODE_MESSAGE | PIPE_WAIT,
+                          1, buffer_size, buffer_size,
+                          0,
+                          &secAttr);
+    if (hTemporaryIn == INVALID_HANDLE_VALUE)
+      goto fail;
+
+    /* And now open the other end, using the inverse access permissions.  This
+       will give us the read and write ends of the pipe.  */
+    secAttr.bInheritHandle = isInheritableOut;
+    hTemporaryOut
+      = CreateFileW (pipeName,
+                     GENERIC_WRITE,
+                     FILE_SHARE_WRITE,
+                     &secAttr,
+                     OPEN_EXISTING,
+                     isOverlappedOut
+                       ? FILE_FLAG_OVERLAPPED
+                       : FILE_ATTRIBUTE_NORMAL,
+                     NULL);
+
+    if (hTemporaryOut == INVALID_HANDLE_VALUE)
+      goto fail;
+
+    /* Ensure that read and write ends are set to the same mode.  MESSAGE mode
+       will honor data boundaries as a whole.  That is, if n bytes are posted
+       at once, n bytes are received together at the other wide as long as n
+       is smaller than buffer size.  Otherwise it's up to buffer size.  BYTE
+       mode is essentially streaming mode. Typically Haskell would benefit from
+       both modes, cabal from byte streaming and iserv from message.  Let's
+       default to MESSAGE.  */
+    DWORD pipeFlags = PIPE_READMODE_MESSAGE;
+    if (!SetNamedPipeHandleState (hTemporaryOut, &pipeFlags, NULL, NULL))
+      goto fail;
+
+    /* Set some optimization flags to make the I/O manager operate more
+       efficiently on these handles.  These mirrors those in
+       `optimizeFileAccess` but we set them here to do so before any data has
+       been put in the HANDLEs.  However these don't always work for sockets and
+       pipes.  So we set them, but can't rely on it.  */
+#if defined(FILE_SKIP_SET_EVENT_ON_HANDLE) && \
+    defined(FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)
+    UCHAR flags = FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
+                  | FILE_SKIP_SET_EVENT_ON_HANDLE;
+    SetFileCompletionNotificationModes (hTemporaryIn, flags);
+    SetFileCompletionNotificationModes (hTemporaryOut, flags);
+#endif
+
+    /* Everything has succeeded so now copy the pointers to the results.  */
+    *pHandleIn = hTemporaryIn;
+    *pHandleOut = hTemporaryOut;
+
+    return TRUE;
+
+fail:
+    /* We have to save the current error before we do another API call.  */
+    maperrno();
+    RpcStringFreeW (&guidStr);
+    if (INVALID_HANDLE_VALUE != hTemporaryIn ) CloseHandle (hTemporaryIn);
+    if (INVALID_HANDLE_VALUE != hTemporaryOut) CloseHandle (hTemporaryOut);
+    return FALSE;
+}
+
+static HANDLE
+createJob ()
+{
+    HANDLE hJob = CreateJobObject (NULL, NULL);
+    JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
+    ZeroMemory(&jeli, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
+    // Configure all child processes associated with the job to terminate when the
+    // Last process in the job terminates. This prevent half dead processes.
+    jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
+
+    if (SetInformationJobObject (hJob, JobObjectExtendedLimitInformation,
+                                 &jeli, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)))
+    {
+        return hJob;
+    }
+
+    maperrno();
+    return NULL;
+}
+
+/* Small helper function that determines how the std handle should be used.
+   if _STDHANDLE is:
+     -1: A new pipe is created.  If ASYNCHRONOUS an asynchronous pipe is created
+         with FILE_FLAG_OVERLAPPED set.  If not then an anonymouse pipe is
+         created without that flag.
+     -2: No handle is created, DESTINATION is NULL.
+     std: If the handle matches the default std handle for the type (i.e. if the
+          handle for input _stdHandle mathed STDIN) then set DESTINATION to that
+          handle.
+     otherwise: We just duplicate the handle to make it inheritable and pass it
+                on.  */
+
+static inline bool
+setStdHandleInfo (LPHANDLE destination, HANDLE _stdhandle,
+                  LPHANDLE hStdRead, LPHANDLE hStdWrite, HANDLE defaultStd,
+                  BOOL isInheritableIn, BOOL isInheritableOut, BOOL asynchronous)
+{
+    BOOL status;
+    assert (destination);
+    assert (hStdRead);
+    assert (hStdWrite);
+
+    LPHANDLE tmpHandle = isInheritableOut ? hStdWrite : hStdRead;
+
+    if (_stdhandle == (HANDLE)-1) {
+        if (!asynchronous
+            && !mkAnonPipe(hStdRead, isInheritableIn, hStdWrite, isInheritableOut))
+            return false;
+        if (asynchronous
+            && !mkNamedPipe(hStdRead, isInheritableIn, !isInheritableIn, hStdWrite, isInheritableOut, !isInheritableOut))
+            return false;
+        *destination = *tmpHandle;
+    } else if (_stdhandle == (HANDLE)-2) {
+        *destination = NULL;
+    } else if (_stdhandle == defaultStd) {
+        // Don't duplicate standard handle, as console handles cannot be
+        // duplicated and inherited. urg.
+        *destination = defaultStd;
+    } else {
+        // The handle might not be inheritable, so duplicate it
+        status = DuplicateHandle(GetCurrentProcess(),
+                                 _stdhandle,
+                                 GetCurrentProcess(), tmpHandle,
+                                 0,
+                                 TRUE, /* inheritable */
+                                 DUPLICATE_SAME_ACCESS);
+        if (!status) return false;
+        *destination = *tmpHandle;
+    }
+
+    return true;
+}
+
+/* Common functionality between the Posix FD version and native HANDLE version
+   of runInteractiveProcess.  The main difference lies in the use of
+   ASYNCHRONOUS which indicates whether the pipes that are created allow for
+   asynchronous access or not.  */
+
+static ProcHandle
+runInteractiveProcessWrapper (
+    wchar_t *cmd, wchar_t *workingDirectory,
+    wchar_t *environment,
+    HANDLE _stdin, HANDLE _stdout, HANDLE _stderr,
+    HANDLE *pStdInput, HANDLE *pStdOutput, HANDLE *pStdError,
+    int flags, bool useJobObject, HANDLE *hJob, bool asynchronous)
+{
+    STARTUPINFO sInfo;
+    PROCESS_INFORMATION pInfo;
+    HANDLE hStdInputRead   = INVALID_HANDLE_VALUE;
+    HANDLE hStdInputWrite  = INVALID_HANDLE_VALUE;
+    HANDLE hStdOutputRead  = INVALID_HANDLE_VALUE;
+    HANDLE hStdOutputWrite = INVALID_HANDLE_VALUE;
+    HANDLE hStdErrorRead   = INVALID_HANDLE_VALUE;
+    HANDLE hStdErrorWrite  = INVALID_HANDLE_VALUE;
+    BOOL close_fds = ((flags & RUN_PROCESS_IN_CLOSE_FDS) != 0);
+    // We always pass a wide environment block, so we MUST set this flag
+    DWORD dwFlags = CREATE_UNICODE_ENVIRONMENT;
+    BOOL inherit;
+
+    ZeroMemory(&sInfo, sizeof(sInfo));
+    sInfo.cb = sizeof(sInfo);
+    sInfo.dwFlags = STARTF_USESTDHANDLES;
+    ZeroMemory(&pInfo, sizeof(pInfo));
+
+    HANDLE defaultStdIn     = GetStdHandle(STD_INPUT_HANDLE);
+    HANDLE defaultStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+    HANDLE defaultStdError  = GetStdHandle(STD_ERROR_HANDLE);
+
+    if (!setStdHandleInfo (&sInfo.hStdInput, _stdin, &hStdInputRead,
+                           &hStdInputWrite, defaultStdIn, TRUE, FALSE,
+                           asynchronous))
+      goto cleanup_err;
+
+    if (!setStdHandleInfo (&sInfo.hStdOutput, _stdout, &hStdOutputRead,
+                           &hStdOutputWrite, defaultStdOutput, FALSE, TRUE,
+                           asynchronous))
+      goto cleanup_err;
+
+    if (!setStdHandleInfo (&sInfo.hStdError, _stderr, &hStdErrorRead,
+                           &hStdErrorWrite, defaultStdError, FALSE, TRUE,
+                           asynchronous))
+      goto cleanup_err;
+
+    if (sInfo.hStdInput     !=  defaultStdIn
+        && sInfo.hStdOutput !=  defaultStdOutput
+        && sInfo.hStdError  !=  defaultStdError
+        && (flags & RUN_PROCESS_IN_NEW_GROUP) == 0)
+            dwFlags |= CREATE_NO_WINDOW;   // Run without console window only when both output and error are redirected
+
+    // See #3231
+    if (close_fds
+        && _stdin == defaultStdIn
+        && _stdout == defaultStdOutput
+        && _stderr == defaultStdError) {
+        inherit = FALSE;
+    } else {
+        inherit = TRUE;
+    }
+
+    if ((flags & RUN_PROCESS_IN_NEW_GROUP) != 0) {
+        dwFlags |= CREATE_NEW_PROCESS_GROUP;
+    }
+    if ((flags & RUN_PROCESS_DETACHED) != 0) {
+        dwFlags |= DETACHED_PROCESS;
+    }
+    if ((flags & RUN_PROCESS_NEW_CONSOLE) != 0) {
+        dwFlags |= CREATE_NEW_CONSOLE;
+    }
+
+    /* If we're going to use a job object, then we have to create
+       the thread suspended.
+       See Note [Windows exec interaction].  */
+    if (useJobObject)
+    {
+        dwFlags |= CREATE_SUSPENDED;
+        *hJob = createJob();
+        if (!*hJob)
+        {
+            goto cleanup_err;
+        }
+    } else {
+        *hJob = NULL;
+    }
+
+    if (!CreateProcess(NULL, cmd, NULL, NULL, inherit, dwFlags, environment, workingDirectory, &sInfo, &pInfo))
+    {
+        goto cleanup_err;
+    }
+
+    if (useJobObject && hJob && *hJob)
+    {
+        // Then associate the process and the job;
+        if (!AssignProcessToJobObject (*hJob, pInfo.hProcess))
+        {
+            goto cleanup_err;
+        }
+
+        // And now that we've associated the new process with the job
+        // we can actively resume it.
+        ResumeThread (pInfo.hThread);
+    }
+
+    CloseHandle(pInfo.hThread);
+
+    // Close the ends of the pipes that were inherited by the
+    // child process.  This is important, otherwise we won't see
+    // EOF on these pipes when the child process exits.
+    if (hStdInputRead   != INVALID_HANDLE_VALUE) CloseHandle(hStdInputRead);
+    if (hStdOutputWrite != INVALID_HANDLE_VALUE) CloseHandle(hStdOutputWrite);
+    if (hStdErrorWrite  != INVALID_HANDLE_VALUE) CloseHandle(hStdErrorWrite);
+
+    // Return the pointers to the handles we need.
+    *pStdInput  = hStdInputWrite;
+    *pStdOutput = hStdOutputRead;
+    *pStdError  = hStdErrorRead;
+
+    return pInfo.hProcess;
+
+cleanup_err:
+    if (hStdInputRead   != INVALID_HANDLE_VALUE) CloseHandle(hStdInputRead);
+    if (hStdInputWrite  != INVALID_HANDLE_VALUE) CloseHandle(hStdInputWrite);
+    if (hStdOutputRead  != INVALID_HANDLE_VALUE) CloseHandle(hStdOutputRead);
+    if (hStdOutputWrite != INVALID_HANDLE_VALUE) CloseHandle(hStdOutputWrite);
+    if (hStdErrorRead   != INVALID_HANDLE_VALUE) CloseHandle(hStdErrorRead);
+    if (hStdErrorWrite  != INVALID_HANDLE_VALUE) CloseHandle(hStdErrorWrite);
+    if (useJobObject && hJob      && *hJob     ) CloseHandle(*hJob);
+
+    maperrno();
+    return NULL;
+}
+
+/* Note [Windows exec interaction]
+
+   The basic issue that process jobs tried to solve is this:
+
+   Say you have two programs A and B. Now A calls B. There are two ways to do this.
+
+   1) You can use the normal CreateProcess API, which is what normal Windows code do.
+      Using this approach, the current waitForProcess works absolutely fine.
+   2) You can call the emulated POSIX function _exec, which of course is supposed to
+      allow the child process to replace the parent.
+
+    With approach 2) waitForProcess falls apart because the Win32's process model does
+    not allow this the same way as linux. _exec is emulated by first making a call to
+    CreateProcess to spawn B and then immediately exiting from A. So you have two
+    different processes.
+
+    waitForProcess is waiting on the termination of A. Because A is immediately killed,
+    waitForProcess will return even though B is still running. This is why for instance
+    the GHC testsuite on Windows had lots of file locked errors.
+
+    This approach creates a new Job and assigned A to the job, but also all future
+    processes spawned by A. This allows us to listen in on events, such as, when all
+    processes in the job are finished, but also allows us to propagate exit codes from
+    _exec calls.
+
+    The only reason we need this at all is because we don't interact with just actual
+    native code on Windows, and instead have a lot of ported POSIX code.
+
+    The Job handle is returned to the user because Jobs have additional benefits as well,
+    such as allowing you to specify resource limits on the to be spawned process.
+ */
+ProcHandle
+runInteractiveProcess (wchar_t *cmd, wchar_t *workingDirectory,
+                       wchar_t *environment,
+                       int fdStdIn, int fdStdOut, int fdStdErr,
+                       int *pfdStdInput, int *pfdStdOutput, int *pfdStdError,
+                       int flags, bool useJobObject, HANDLE *hJob)
+{
+    HANDLE pStdInput = INVALID_HANDLE_VALUE;
+    HANDLE pStdOutput = INVALID_HANDLE_VALUE;
+    HANDLE pStdError = INVALID_HANDLE_VALUE;
+
+    ProcHandle result
+      = runInteractiveProcessWrapper (cmd, workingDirectory, environment,
+                                      (HANDLE) (fdStdIn  < 0 ? fdStdIn : _get_osfhandle(fdStdIn)),
+                                      (HANDLE) (fdStdOut < 0 ? fdStdOut : _get_osfhandle(fdStdOut)),
+                                      (HANDLE) (fdStdErr < 0 ? fdStdErr : _get_osfhandle(fdStdErr)),
+                                      &pStdInput, &pStdOutput, &pStdError,
+                                      flags, useJobObject, hJob, FALSE);
+
+    if (result) {
+        *pfdStdInput  = _open_osfhandle((intptr_t) pStdInput,  _O_WRONLY);
+        *pfdStdOutput = _open_osfhandle((intptr_t) pStdOutput, _O_RDONLY);
+        *pfdStdError  = _open_osfhandle((intptr_t) pStdError,  _O_RDONLY);
+    }
+
+    return result;
+}
+
+/* This function is the same as runInteractiveProcess except it works directly
+   on Windows HANDLE rather than pseudo FDs.  This allows us to use the pipes
+   returned here asynchronously and also need less system calls while working
+   with the new I/O manager.  */
+ProcHandle
+runInteractiveProcessHANDLE (
+    wchar_t *cmd, wchar_t *workingDirectory,
+    wchar_t *environment,
+    HANDLE _stdin, HANDLE _stdout, HANDLE _stderr,
+    HANDLE *pStdInput, HANDLE *pStdOutput, HANDLE *pStdError,
+    int flags, bool useJobObject, HANDLE *hJob)
+{
+  return runInteractiveProcessWrapper (cmd, workingDirectory, environment,
+                                       _stdin, _stdout, _stderr,
+                                       pStdInput, pStdOutput, pStdError,
+                                       flags, useJobObject, hJob, TRUE);
+}
+
+int
+terminateProcess (ProcHandle handle)
+{
+    if (!TerminateProcess ((HANDLE) handle, 1)) {
+        DWORD e = GetLastError();
+        DWORD exitCode;
+        /*
+        This is a crude workaround that is taken from libuv. For some reason
+        TerminateProcess() can fail with ERROR_ACCESS_DENIED if the process
+        already terminated. This situation can be detected by using
+        GetExitCodeProcess() to check if the exit code is availble. Unfortunately
+        this function succeeds and gives exit code 259 (STILL_ACTIVE) if the
+        process is still running. So there is no way to ditinguish a process
+        that exited with 259 and a process that did not exit because we had
+        insufficient access to terminate it.
+        One would expect WaitForSingleObject() to be the solid solution. But this
+        function does return WAIT_TIMEOUT in that situation. Even if called
+        after GetExitCodeProcess().
+        */
+        if (e == ERROR_ACCESS_DENIED && GetExitCodeProcess((HANDLE) handle, &exitCode) && exitCode != STILL_ACTIVE)
+            return 0;
+
+        SetLastError(e);
+        maperrno();
+        return -1;
+    }
+    return 0;
+}
+
+int
+terminateJob (ProcHandle handle)
+{
+    if (!TerminateJobObject ((HANDLE)handle, 1)) {
+        maperrno();
+        return -1;
+    }
+    return 0;
+}
+
+int
+getProcessExitCode (ProcHandle handle, int *pExitCode)
+{
+    *pExitCode = 0;
+
+    if (WaitForSingleObject((HANDLE) handle, 1) == WAIT_OBJECT_0)
+    {
+        if (GetExitCodeProcess((HANDLE) handle, (DWORD *) pExitCode) == 0)
+        {
+            maperrno();
+            return -1;
+        }
+        return 1;
+    }
+
+    return 0;
+}
+
+int
+waitForProcess (ProcHandle handle, int *pret)
+{
+    DWORD retCode;
+
+    if (WaitForSingleObject((HANDLE) handle, INFINITE) == WAIT_OBJECT_0)
+    {
+        if (GetExitCodeProcess((HANDLE) handle, &retCode) == 0)
+        {
+            maperrno();
+            return -1;
+        }
+        *pret = retCode;
+        return 0;
+    }
+
+    maperrno();
+    return -1;
+}
+
+// Returns true on success.
+int
+waitForJobCompletion ( HANDLE hJob )
+{
+    int process_count = 16;
+    JOBOBJECT_BASIC_PROCESS_ID_LIST *pid_list = NULL;
+
+    while (true) {
+      size_t pid_list_size = sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) + sizeof(ULONG_PTR) * (process_count - 1);
+
+      if (pid_list == NULL) {
+        pid_list = malloc(pid_list_size);
+        if (pid_list == NULL) {
+          errno = ENOMEM;
+          return false;
+        }
+        pid_list->NumberOfAssignedProcesses = process_count;
+      }
+
+      // Find a process in the job...
+      bool success = QueryInformationJobObject(
+          hJob,
+          JobObjectBasicProcessIdList,
+          pid_list,
+          pid_list_size,
+          NULL);
+
+      if (!success && GetLastError() == ERROR_MORE_DATA) {
+        process_count *= 2;
+        free(pid_list);
+        pid_list = NULL;
+        continue;
+      } else if (!success) {
+        free(pid_list);
+        maperrno();
+        return false;
+      }
+      if (pid_list->NumberOfProcessIdsInList == 0) {
+        // We're done
+        free(pid_list);
+        return true;
+      }
+
+      HANDLE pHwnd;
+      bool found_p;
+
+      /* Find the first non-terminated handle.  */
+      for (DWORD i = 0; i < pid_list->NumberOfProcessIdsInList; i++) {
+        pHwnd = OpenProcess(SYNCHRONIZE, FALSE, pid_list->ProcessIdList[i]);
+        int code = 0;
+        found_p = pHwnd && getProcessExitCode (pHwnd, &code) != -1 && code != STILL_ACTIVE;
+        if (found_p)
+          break;
+      }
+
+      /* All processes were terminated already.  */
+      if (!found_p)
+        return true;
+
+      if (pHwnd == NULL) {
+        switch (GetLastError()) {
+          case ERROR_INVALID_PARAMETER:
+          case ERROR_INVALID_HANDLE:
+            // Presumably the process terminated; try again.
+            continue;
+          default:
+            free(pid_list);
+            maperrno();
+            return false;
+        }
+      }
+
+      // Wait for it to finish...
+      DWORD result = WaitForSingleObject(pHwnd, 200);
+      if (result == WAIT_TIMEOUT) {
+        int code = 0;
+        /* Current process is waiting to terminate. skip.  */
+        if (getProcessExitCode (pHwnd, &code) != -1 && code != STILL_ACTIVE)
+          continue ;
+      } else if (result != WAIT_OBJECT_0) {
+        free(pid_list);
+        maperrno();
+        CloseHandle(pHwnd);
+        return false;
+      }
+
+      // The process signalled, loop again to try the next process.
+      CloseHandle(pHwnd);
+    }
+}
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,6 +1,255 @@
 # Changelog for [`process` package](http://hackage.haskell.org/package/process)
 
-## 1.3.0.0 (unreleased)
+## 1.6.30.0 *June 2026*
+
+* darwin: Allow posix_spawn_file_actions_addchdir to be missing when
+  linking against process ([#377](https://github.com/haskell/process/pull/377))
+
+## 1.6.29.0 *May 2026*
+
+* Stub out `runProcess.c` on wasm32 ([#366](https://github.com/haskell/process/pull/366))
+* Fix segmentation faults on MacOS 15 caused by NULL symbols created by toolchains that can compile for MacOS 26 ([#363](https://github.com/haskell/process/pull/363))
+
+## 1.6.28.0 *April 2026*
+
+* Add `callCreateProcess`
+* Improve Haddock
+
+## 1.6.27.0 *March 2026*
+
+* Support being configured without fork
+* Fix `@since` annotations
+
+## 1.6.26.1 *May 2025*
+
+* Regenerate `configure` script (#343)
+
+## 1.6.26.0 *April 2025*
+
+* Add `System.Process.Environment.OsString`.
+* Bumps `base >= 4.12.0.0` (GHC 8.6+), `filepath >= 1.4.100.0`,
+  `unix >= 2.8.0.0`, and `Win32 >= 2.14.1.0`.
+* Drops support for GHC < 8.6.
+
+## 1.6.25.0 *September 2024*
+
+* Fix build with Javascript backend ([#327](https://github.com/haskell/process/issues/327))
+
+## 1.6.24.0 *September 2024*
+
+* Fix detection of `posix_spawn_file_actions_addchdir[_np]` ([#303](https://github.com/haskell/process/issues/303))
+
+## 1.6.23.0 *September 2024*
+
+* Fix command-line escaping logic on Windows when the command file ends with
+  a space or a dot. This is a follow-up for
+  [HSEC-2024-0003](https://github.com/haskell/security-advisories/tree/main/advisories/hackage/process/HSEC-2024-0003.md).
+* Migitate another manifestation of the BatBadBut vulnerability via
+  unescaped `%` expansions. This is another follow-up for
+  [HSEC-2024-0003](https://github.com/haskell/security-advisories/tree/main/advisories/hackage/process/HSEC-2024-0003.md).
+  ([#313](https://github.com/haskell/process/issues/313))
+
+## 1.6.22.0 *August 2024*
+
+* Allow NUL to appear in arguments under POSIX. See
+  https://github.com/haskell/process/pull/320.  Thanks to @mmhat.
+
+## 1.6.21.0 *July 2024*
+
+* No longer attach finalizers to `Handle`s created by the
+  `System.Process.CommunicationHandle` API. Instead, all file descriptors are
+  manually closed by the API.
+
+  This fixes a bug in which a file descriptor could be closed multiple times.
+
+## 1.6.20.0 *April 2024*
+
+* Introduce `System.Process.CommunicationHandle`, allowing for platform-independent
+  inter-process communication using `Handle`s.
+* Expose `withForkWait` and `ignoreSigPipe` from `System.Process.Internals`.
+* Define new internal functions `rawFdToHandle` and (Windows only) `rawHANDLEToHandle`,
+  exported from `System.Process.Common`.
+
+## 1.6.19.0 *April 2024*
+
+* Adjust command-line escaping logic on Windows to ensure that occurrences of
+  characters with special significance to the Windows batch interpreter are
+  properly escaped in arguments passed to `.bat` and `.cmd` processes.
+  This addresses
+  [HSEC-2024-0003](https://github.com/haskell/security-advisories/tree/main/advisories/hackage/process/HSEC-2024-0003.md).
+* Fix double-closing of stdin/stdout/stderr fds with POSIX `fork/exec` backend.
+  [#306](https://github.com/haskell/process/issues/306)
+* Add support for `posix_spawn_file_actions_addchdir_np`
+
+## 1.6.18.0 *September 2023*
+
+* Fix deadlock when waiting for process completion and process jobs [#273](https://github.com/haskell/process/issues/273)
+* Support `delegate_ctlc` on Windows. [#278](https://github.com/haskell/process/pull/278)
+* Drop support for `vfork` [#261](https://github.com/haskell/process/pull/261)
+* Javascript backend support
+* Fix potential segmentation fault on macOS [#295](https://github.com/haskell/process/pull/295)
+
+## 1.6.17.0 *February 2023*
+
+* Improved documentation for the `OpenExtHandle` constructor.
+
+## 1.6.16.0 *October 2022*
+
+* `posix_spawn`: Don't rely on addclose not failing for closed fds [#251](https://github.com/haskell/process/issues/251)
+* Support unix 2.8 [#258](https://github.com/haskell/process/issues/258)
+
+## 1.6.15.0 *August 2022*
+
+* Correct permissions on createPipe on Windows [234](https://github.com/haskell/process/pull/234)
+* Ensure that both ends of pipes on Windows are created in the same mode  [234](https://github.com/haskell/process/pull/234)
+* Fixed an issue with WINIO where giving an application an inherited pipe can cause it to misbehave [245](https://github.com/haskell/process/pull/245)
+* Set the encoding on WINIO created pipes to the local encoding as with MIO [248](https://github.com/haskell/process/pull/248)
+* cbits/fork-exec: Don't dup2 identical fds [#250](https://github.com/haskell/process/pull/250)
+
+## 1.6.14.0 *February 2022*
+
+* posix: Ensure that `errno` is set after `posix_spawnp` fails [#228](https://github.com/haskell/process/pull/228)
+* Fix `waitForProcess` not closing process handles with `delegate_ctlc` [#231](https://github.com/haskell/process/pull/231)
+* Don't use `posix_spawn` on platforms where it does not report `ENOENT` in caes where the
+  requested executable does not exist [#224](https://github.com/haskell/process/issues/224)
+* Ensure that `find_executable` correctly-locates executables when a change in
+  working directory is requested [#219](https://github.com/haskell/process/issues/219)
+* Fix capitalization error allowing `execvpe` to be used when available.
+
+## 1.6.13.2 *July 2021*
+
+* `posix_spawn`: Don't attempt to `dup2` identical fds [#214](https://github.com/haskell/process/pull/214)
+
+## 1.6.13.1 *July 2021*
+
+* Patches for the previous release
+
+## 1.6.13.0 *July 2021*
+
+* Refactoring of POSIX process logic [#208](https://github.com/haskell/process/pull/208)
+
+## 1.6.12.0 *June 2021*
+
+* Add function `getCurrentPid` to get the currently executing process' ID [#205](https://github.com/haskell/process/pull/205)
+
+## 1.6.11.0 *January 2021*
+
+* Windows: Add support for new I/O manager in GHC 8.12[#177](https://github.com/haskell/process/pull/177)
+* Deprecate use of `createPipeFd` in favor of `createPipe`
+* Fix MVar re-entrant problem on Windows with `terminateProcess` and process jobs. See [#199](https://github.com/haskell/process/pull/199)
+
+## 1.6.10.0 *June 2020*
+
+* Give a usable buffer to `_pipe` on Windows [#182](https://github.com/haskell/process/pull/182)
+
+## 1.6.9 *May 2020*
+
+* Windows: Fix buffer size of `QueryInformationJobObject` request [#176](https://github.com/haskell/process/pull/176/files)
+
+## 1.6.8.2 *March 2020*
+
+* Fix another process wait bug on Windows.
+
+## 1.6.8.1 *March 2020*
+
+* Fix a few warnings on Windows.
+
+## 1.6.8.0 *February 2020*
+
+* Fix several bugs on Windows where use of process jobs would result
+  in the process being prematurely terminated. See
+  [#168](https://github.com/haskell/process/168).
+
+## 1.6.7.0 *November 2019*
+
+* Fix a race condition on Windows that happens when you use process jobs and one of
+  the child processes terminates but doesn't release its resources immediately.
+  Control returns to the caller too soon in this scenario. See [#159](https://github.com/haskell/process/pull/159)
+
+## 1.6.6.0 *October 2019*
+
+* Fix a potential privilege escalation issue (or, more precisely, privileges
+  not being dropped when this was the user's intent) where the groups of the
+  spawning process's user would be incorrectly retained due to a missing call to
+  `initgroups` [#149].
+* Bug fix: Prevent stripping undecodable bytes from environment variables
+  when in a non-unicode locale.
+  [#152](https://github.com/haskell/process/issues/152)
+* Expose `runInteractiveProcess_lock` in `System.Process.Internals`
+  [#154](https://github.com/haskell/process/pull/154)
+
+## 1.6.5.1 *June 2019*
+
+* Version bound bumps
+* Slightly nicer error messages for internal errors
+
+## 1.6.5.0 *December 2018*
+
+* Bug fix: On Windows ignore ERROR_ACCESS_DENIED for TerminateProcess() if the process did terminate
+  [#110](https://github.com/haskell/process/issues/110)
+* Improve documentation of the `NoStream` data constructor
+
+## 1.6.4.0 *July 2018*
+
+* Bug fix: Don't leak pipes on failure
+  [#122](https://github.com/haskell/process/issues/122)
+* Expose `cleanupProcess` from `System.Process`
+  [#130](https://github.com/haskell/process/pull/130)
+* Drop support for GHC before 7.10.3
+
+## 1.6.3.0 *January 2018*
+
+* Added `getPid` and export of platform specific `Pid` type
+  [#109](https://github.com/haskell/process/pull/109)
+
+## 1.6.2.0 *October 2017*
+
+* Allow async exceptions to be delivered to masked thread calling `waitForProcess`
+  [#101](https://github.com/haskell/process/pull/101)
+* Update Win32 package version to 2.6.x
+
+## 1.6.1.0 *July 2017*
+
+* Expose `CGid`, `GroupID`, and `UserID` from `System.Process.Internals`
+  [#90](https://github.com/haskell/process/issues/90)
+  [#91](https://github.com/haskell/process/pull/91)
+
+## 1.6.0.0 *February 2017*
+
+* Fix: waitForProcess race condition
+  [#46](https://github.com/haskell/process/issues/46)
+  [#58](https://github.com/haskell/process/pull/58)
+
+## 1.5.0.0 *February 2017*
+
+* Bug fix: Don't close already closed pipes
+  [#81](https://github.com/haskell/process/pull/81)
+* Relax version bounds of Win32 to allow 2.5.
+* Add support for monitoring process tree for termination with the parameter `use_process_jobs`
+  in `CreateProcess` on Windows. Also added a function `terminateJob` to kill entire process tree.
+
+## 1.4.3.0 *December 2016*
+
+* New exposed `withCreateProcess`
+* Derive `Show` and `Eq` for `CreateProcess`, `CmdSpec`, and `StdStream`
+
+## 1.4.2.0 *January 2016*
+
+* Added `createPipeFD` [#52](https://github.com/haskell/process/pull/52)
+    * New function `createPipeFD` added which returns a POSIX File Descriptor (CInt)
+      instead of a GHC Handle to a pipe
+
+## 1.4.1.0 *November 2015*
+
+* Use less CPP [#47](https://github.com/haskell/process/pull/47)
+    * Refactor to have separate Windows and POSIX modules internally
+    * Remove the broken non-GHC code paths
+
+## 1.4.0.0 *November 2015*
+
+* Added `child_user` and `child_group` to `CreateProcess` for unix. [#45](https://github.com/haskell/process/pull/45)
+
+## 1.3.0.0 *August 2015*
 
 * Add `StdStream(NoStream)` to have standard handles closed. [#13](https://github.com/haskell/process/pull/13)
 * Support for Windows `DETACHED_PROCESS` and `setsid` [#32](https://github.com/haskell/process/issues/32)
diff --git a/configure b/configure
--- a/configure
+++ b/configure
@@ -1,4826 +1,5213 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Haskell process package 1.0.
-#
-# Report bugs to <libraries@haskell.org>.
-#
-#
-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
-#
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
-  emulate sh
-  NULLCMD=:
-  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in #(
-  *posix*) :
-    set -o posix ;; #(
-  *) :
-     ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-	expr "X$arg" : "X\\(.*\\)$as_nl";
-	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  PATH_SEPARATOR=:
-  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
-    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
-      PATH_SEPARATOR=';'
-  }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""	$as_nl"
-
-# Find who we are.  Look in the path if we contain no directory separator.
-as_myself=
-case $0 in #((
-  *[\\/]* ) as_myself=$0 ;;
-  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-  done
-IFS=$as_save_IFS
-
-     ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
-  as_myself=$0
-fi
-if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# Use a proper internal environment variable to ensure we don't fall
-  # into an infinite loop, continuously re-executing ourselves.
-  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
-    _as_can_reexec=no; export _as_can_reexec;
-    # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
-  *v*x* | *x*v* ) as_opts=-vx ;;
-  *v* ) as_opts=-v ;;
-  *x* ) as_opts=-x ;;
-  * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-as_fn_exit 255
-  fi
-  # We don't want this to propagate to other subprocesses.
-          { _as_can_reexec=; unset _as_can_reexec;}
-if test "x$CONFIG_SHELL" = x; then
-  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
-  emulate sh
-  NULLCMD=:
-  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '\${1+\"\$@\"}'='\"\$@\"'
-  setopt NO_GLOB_SUBST
-else
-  case \`(set -o) 2>/dev/null\` in #(
-  *posix*) :
-    set -o posix ;; #(
-  *) :
-     ;;
-esac
-fi
-"
-  as_required="as_fn_return () { (exit \$1); }
-as_fn_success () { as_fn_return 0; }
-as_fn_failure () { as_fn_return 1; }
-as_fn_ret_success () { return 0; }
-as_fn_ret_failure () { return 1; }
-
-exitcode=0
-as_fn_success || { exitcode=1; echo as_fn_success failed.; }
-as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
-as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
-as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
-
-else
-  exitcode=1; echo positional parameters were not saved.
-fi
-test x\$exitcode = x0 || exit 1
-test -x / || exit 1"
-  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
-  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
-  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
-  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
-test \$(( 1 + 1 )) = 2 || exit 1"
-  if (eval "$as_required") 2>/dev/null; then :
-  as_have_required=yes
-else
-  as_have_required=no
-fi
-  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
-
-else
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_found=false
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  as_found=:
-  case $as_dir in #(
-	 /*)
-	   for as_base in sh bash ksh sh5; do
-	     # Try only shells that exist, to save several forks.
-	     as_shell=$as_dir/$as_base
-	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
-		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
-  CONFIG_SHELL=$as_shell as_have_required=yes
-		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
-  break 2
-fi
-fi
-	   done;;
-       esac
-  as_found=false
-done
-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
-	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
-  CONFIG_SHELL=$SHELL as_have_required=yes
-fi; }
-IFS=$as_save_IFS
-
-
-      if test "x$CONFIG_SHELL" != x; then :
-  export CONFIG_SHELL
-             # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
-  *v*x* | *x*v* ) as_opts=-vx ;;
-  *v* ) as_opts=-v ;;
-  *x* ) as_opts=-x ;;
-  * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-exit 255
-fi
-
-    if test x$as_have_required = xno; then :
-  $as_echo "$0: This script requires a shell more modern than all"
-  $as_echo "$0: the shells that I found on your system."
-  if test x${ZSH_VERSION+set} = xset ; then
-    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
-    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
-  else
-    $as_echo "$0: Please tell bug-autoconf@gnu.org and
-$0: libraries@haskell.org about your system, including any
-$0: error possibly output before this message. Then install
-$0: a modern shell, or manually run the script under such a
-$0: shell if you do have one."
-  fi
-  exit 1
-fi
-fi
-fi
-SHELL=${CONFIG_SHELL-/bin/sh}
-export SHELL
-# Unset more variables known to interfere with behavior of common tools.
-CLICOLOR_FORCE= GREP_OPTIONS=
-unset CLICOLOR_FORCE GREP_OPTIONS
-
-## --------------------- ##
-## M4sh Shell Functions. ##
-## --------------------- ##
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
-  { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
-  return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
-  set +e
-  as_fn_set_status $1
-  exit $1
-} # as_fn_exit
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
-  case $as_dir in #(
-  -*) as_dir=./$as_dir;;
-  esac
-  test -d "$as_dir" || eval $as_mkdir_p || {
-    as_dirs=
-    while :; do
-      case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
-      *) as_qdir=$as_dir;;
-      esac
-      as_dirs="'$as_qdir' $as_dirs"
-      as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_dir" : 'X\(//\)[^/]' \| \
-	 X"$as_dir" : 'X\(//\)$' \| \
-	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-      test -d "$as_dir" && break
-    done
-    test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
-  test -f "$1" && test -x "$1"
-} # as_fn_executable_p
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
-  eval 'as_fn_append ()
-  {
-    eval $1+=\$2
-  }'
-else
-  as_fn_append ()
-  {
-    eval $1=\$$1\$2
-  }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
-  eval 'as_fn_arith ()
-  {
-    as_val=$(( $* ))
-  }'
-else
-  as_fn_arith ()
-  {
-    as_val=`expr "$@" || test $? -eq 1`
-  }
-fi # as_fn_arith
-
-
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
-as_fn_error ()
-{
-  as_status=$1; test $as_status -eq 0 && as_status=1
-  if test "$4"; then
-    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
-  fi
-  $as_echo "$as_me: error: $2" >&2
-  as_fn_exit $as_status
-} # as_fn_error
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
-  as_basename=basename
-else
-  as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
-	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-
-  as_lineno_1=$LINENO as_lineno_1a=$LINENO
-  as_lineno_2=$LINENO as_lineno_2a=$LINENO
-  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
-  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
-  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
-  sed -n '
-    p
-    /[$]LINENO/=
-  ' <$as_myself |
-    sed '
-      s/[$]LINENO.*/&-/
-      t lineno
-      b
-      :lineno
-      N
-      :loop
-      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
-      t loop
-      s/-\n.*//
-    ' >$as_me.lineno &&
-  chmod +x "$as_me.lineno" ||
-    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
-  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
-  # already done that, so ensure we don't try to do so again and fall
-  # in an infinite loop.  This has already happened in practice.
-  _as_can_reexec=no; export _as_can_reexec
-  # Don't try to exec as it changes $[0], causing all sort of problems
-  # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensitive to this).
-  . "./$as_me.lineno"
-  # Exit status is that of the last command.
-  exit
-}
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
-  case `echo 'xy\c'` in
-  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
-  xy)  ECHO_C='\c';;
-  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
-       ECHO_T='	';;
-  esac;;
-*)
-  ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
-  rm -f conf$$.dir/conf$$.file
-else
-  rm -f conf$$.dir
-  mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
-  if ln -s conf$$.file conf$$ 2>/dev/null; then
-    as_ln_s='ln -s'
-    # ... but there are two gotchas:
-    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -pR'.
-    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -pR'
-  elif ln conf$$.file conf$$ 2>/dev/null; then
-    as_ln_s=ln
-  else
-    as_ln_s='cp -pR'
-  fi
-else
-  as_ln_s='cp -pR'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
-  as_mkdir_p='mkdir -p "$as_dir"'
-else
-  test -d ./-p && rmdir ./-p
-  as_mkdir_p=false
-fi
-
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-test -n "$DJDIR" || exec 7<&0 </dev/null
-exec 6>&1
-
-# Name of the host.
-# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-
-# Identity of this package.
-PACKAGE_NAME='Haskell process package'
-PACKAGE_TARNAME='process'
-PACKAGE_VERSION='1.0'
-PACKAGE_STRING='Haskell process package 1.0'
-PACKAGE_BUGREPORT='libraries@haskell.org'
-PACKAGE_URL=''
-
-ac_unique_file="include/runProcess.h"
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-#  include <memory.h>
-# endif
-# include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
-ac_subst_vars='LTLIBOBJS
-LIBOBJS
-EGREP
-GREP
-CPP
-OBJEXT
-EXEEXT
-ac_ct_CC
-CPPFLAGS
-LDFLAGS
-CFLAGS
-CC
-target_alias
-host_alias
-build_alias
-LIBS
-ECHO_T
-ECHO_N
-ECHO_C
-DEFS
-mandir
-localedir
-libdir
-psdir
-pdfdir
-dvidir
-htmldir
-infodir
-docdir
-oldincludedir
-includedir
-localstatedir
-sharedstatedir
-sysconfdir
-datadir
-datarootdir
-libexecdir
-sbindir
-bindir
-program_transform_name
-prefix
-exec_prefix
-PACKAGE_URL
-PACKAGE_BUGREPORT
-PACKAGE_STRING
-PACKAGE_VERSION
-PACKAGE_TARNAME
-PACKAGE_NAME
-PATH_SEPARATOR
-SHELL'
-ac_subst_files=''
-ac_user_opts='
-enable_option_checking
-with_cc
-'
-      ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-LIBS
-CPPFLAGS
-CPP'
-
-
-# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
-ac_unrecognized_opts=
-ac_unrecognized_sep=
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-cache_file=/dev/null
-exec_prefix=NONE
-no_create=
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-verbose=
-x_includes=NONE
-x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
-
-ac_prev=
-ac_dashdash=
-for ac_option
-do
-  # If the previous option needs an argument, assign it.
-  if test -n "$ac_prev"; then
-    eval $ac_prev=\$ac_option
-    ac_prev=
-    continue
-  fi
-
-  case $ac_option in
-  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *=)   ac_optarg= ;;
-  *)    ac_optarg=yes ;;
-  esac
-
-  # Accept the important Cygnus configure options, so we can diagnose typos.
-
-  case $ac_dashdash$ac_option in
-  --)
-    ac_dashdash=yes ;;
-
-  -bindir | --bindir | --bindi | --bind | --bin | --bi)
-    ac_prev=bindir ;;
-  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
-    bindir=$ac_optarg ;;
-
-  -build | --build | --buil | --bui | --bu)
-    ac_prev=build_alias ;;
-  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
-    build_alias=$ac_optarg ;;
-
-  -cache-file | --cache-file | --cache-fil | --cache-fi \
-  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
-    ac_prev=cache_file ;;
-  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
-  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
-    cache_file=$ac_optarg ;;
-
-  --config-cache | -C)
-    cache_file=config.cache ;;
-
-  -datadir | --datadir | --datadi | --datad)
-    ac_prev=datadir ;;
-  -datadir=* | --datadir=* | --datadi=* | --datad=*)
-    datadir=$ac_optarg ;;
-
-  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
-  | --dataroo | --dataro | --datar)
-    ac_prev=datarootdir ;;
-  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
-  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
-    datarootdir=$ac_optarg ;;
-
-  -disable-* | --disable-*)
-    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
-    ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
-    case $ac_user_opts in
-      *"
-"enable_$ac_useropt"
-"*) ;;
-      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
-	 ac_unrecognized_sep=', ';;
-    esac
-    eval enable_$ac_useropt=no ;;
-
-  -docdir | --docdir | --docdi | --doc | --do)
-    ac_prev=docdir ;;
-  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
-    docdir=$ac_optarg ;;
-
-  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
-    ac_prev=dvidir ;;
-  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
-    dvidir=$ac_optarg ;;
-
-  -enable-* | --enable-*)
-    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
-    ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
-    case $ac_user_opts in
-      *"
-"enable_$ac_useropt"
-"*) ;;
-      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
-	 ac_unrecognized_sep=', ';;
-    esac
-    eval enable_$ac_useropt=\$ac_optarg ;;
-
-  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
-  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
-  | --exec | --exe | --ex)
-    ac_prev=exec_prefix ;;
-  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
-  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
-  | --exec=* | --exe=* | --ex=*)
-    exec_prefix=$ac_optarg ;;
-
-  -gas | --gas | --ga | --g)
-    # Obsolete; use --with-gas.
-    with_gas=yes ;;
-
-  -help | --help | --hel | --he | -h)
-    ac_init_help=long ;;
-  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
-    ac_init_help=recursive ;;
-  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
-    ac_init_help=short ;;
-
-  -host | --host | --hos | --ho)
-    ac_prev=host_alias ;;
-  -host=* | --host=* | --hos=* | --ho=*)
-    host_alias=$ac_optarg ;;
-
-  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
-    ac_prev=htmldir ;;
-  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
-  | --ht=*)
-    htmldir=$ac_optarg ;;
-
-  -includedir | --includedir | --includedi | --included | --include \
-  | --includ | --inclu | --incl | --inc)
-    ac_prev=includedir ;;
-  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
-  | --includ=* | --inclu=* | --incl=* | --inc=*)
-    includedir=$ac_optarg ;;
-
-  -infodir | --infodir | --infodi | --infod | --info | --inf)
-    ac_prev=infodir ;;
-  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
-    infodir=$ac_optarg ;;
-
-  -libdir | --libdir | --libdi | --libd)
-    ac_prev=libdir ;;
-  -libdir=* | --libdir=* | --libdi=* | --libd=*)
-    libdir=$ac_optarg ;;
-
-  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
-  | --libexe | --libex | --libe)
-    ac_prev=libexecdir ;;
-  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
-  | --libexe=* | --libex=* | --libe=*)
-    libexecdir=$ac_optarg ;;
-
-  -localedir | --localedir | --localedi | --localed | --locale)
-    ac_prev=localedir ;;
-  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
-    localedir=$ac_optarg ;;
-
-  -localstatedir | --localstatedir | --localstatedi | --localstated \
-  | --localstate | --localstat | --localsta | --localst | --locals)
-    ac_prev=localstatedir ;;
-  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
-  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
-    localstatedir=$ac_optarg ;;
-
-  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
-    ac_prev=mandir ;;
-  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
-    mandir=$ac_optarg ;;
-
-  -nfp | --nfp | --nf)
-    # Obsolete; use --without-fp.
-    with_fp=no ;;
-
-  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-  | --no-cr | --no-c | -n)
-    no_create=yes ;;
-
-  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
-    no_recursion=yes ;;
-
-  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
-  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
-  | --oldin | --oldi | --old | --ol | --o)
-    ac_prev=oldincludedir ;;
-  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
-  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
-  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
-    oldincludedir=$ac_optarg ;;
-
-  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
-    ac_prev=prefix ;;
-  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
-    prefix=$ac_optarg ;;
-
-  -program-prefix | --program-prefix | --program-prefi | --program-pref \
-  | --program-pre | --program-pr | --program-p)
-    ac_prev=program_prefix ;;
-  -program-prefix=* | --program-prefix=* | --program-prefi=* \
-  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
-    program_prefix=$ac_optarg ;;
-
-  -program-suffix | --program-suffix | --program-suffi | --program-suff \
-  | --program-suf | --program-su | --program-s)
-    ac_prev=program_suffix ;;
-  -program-suffix=* | --program-suffix=* | --program-suffi=* \
-  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
-    program_suffix=$ac_optarg ;;
-
-  -program-transform-name | --program-transform-name \
-  | --program-transform-nam | --program-transform-na \
-  | --program-transform-n | --program-transform- \
-  | --program-transform | --program-transfor \
-  | --program-transfo | --program-transf \
-  | --program-trans | --program-tran \
-  | --progr-tra | --program-tr | --program-t)
-    ac_prev=program_transform_name ;;
-  -program-transform-name=* | --program-transform-name=* \
-  | --program-transform-nam=* | --program-transform-na=* \
-  | --program-transform-n=* | --program-transform-=* \
-  | --program-transform=* | --program-transfor=* \
-  | --program-transfo=* | --program-transf=* \
-  | --program-trans=* | --program-tran=* \
-  | --progr-tra=* | --program-tr=* | --program-t=*)
-    program_transform_name=$ac_optarg ;;
-
-  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
-    ac_prev=pdfdir ;;
-  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
-    pdfdir=$ac_optarg ;;
-
-  -psdir | --psdir | --psdi | --psd | --ps)
-    ac_prev=psdir ;;
-  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
-    psdir=$ac_optarg ;;
-
-  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-  | -silent | --silent | --silen | --sile | --sil)
-    silent=yes ;;
-
-  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
-    ac_prev=sbindir ;;
-  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
-  | --sbi=* | --sb=*)
-    sbindir=$ac_optarg ;;
-
-  -sharedstatedir | --sharedstatedir | --sharedstatedi \
-  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
-  | --sharedst | --shareds | --shared | --share | --shar \
-  | --sha | --sh)
-    ac_prev=sharedstatedir ;;
-  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
-  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
-  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
-  | --sha=* | --sh=*)
-    sharedstatedir=$ac_optarg ;;
-
-  -site | --site | --sit)
-    ac_prev=site ;;
-  -site=* | --site=* | --sit=*)
-    site=$ac_optarg ;;
-
-  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
-    ac_prev=srcdir ;;
-  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
-    srcdir=$ac_optarg ;;
-
-  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
-  | --syscon | --sysco | --sysc | --sys | --sy)
-    ac_prev=sysconfdir ;;
-  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
-  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
-    sysconfdir=$ac_optarg ;;
-
-  -target | --target | --targe | --targ | --tar | --ta | --t)
-    ac_prev=target_alias ;;
-  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
-    target_alias=$ac_optarg ;;
-
-  -v | -verbose | --verbose | --verbos | --verbo | --verb)
-    verbose=yes ;;
-
-  -version | --version | --versio | --versi | --vers | -V)
-    ac_init_version=: ;;
-
-  -with-* | --with-*)
-    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
-    ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
-    case $ac_user_opts in
-      *"
-"with_$ac_useropt"
-"*) ;;
-      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
-	 ac_unrecognized_sep=', ';;
-    esac
-    eval with_$ac_useropt=\$ac_optarg ;;
-
-  -without-* | --without-*)
-    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
-    ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
-    case $ac_user_opts in
-      *"
-"with_$ac_useropt"
-"*) ;;
-      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
-	 ac_unrecognized_sep=', ';;
-    esac
-    eval with_$ac_useropt=no ;;
-
-  --x)
-    # Obsolete; use --with-x.
-    with_x=yes ;;
-
-  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
-  | --x-incl | --x-inc | --x-in | --x-i)
-    ac_prev=x_includes ;;
-  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
-  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
-    x_includes=$ac_optarg ;;
-
-  -x-libraries | --x-libraries | --x-librarie | --x-librari \
-  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
-    ac_prev=x_libraries ;;
-  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
-  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
-    x_libraries=$ac_optarg ;;
-
-  -*) as_fn_error $? "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information"
-    ;;
-
-  *=*)
-    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
-    # Reject names that are not valid shell variable names.
-    case $ac_envvar in #(
-      '' | [0-9]* | *[!_$as_cr_alnum]* )
-      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
-    esac
-    eval $ac_envvar=\$ac_optarg
-    export $ac_envvar ;;
-
-  *)
-    # FIXME: should be removed in autoconf 3.0.
-    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
-    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
-    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
-    ;;
-
-  esac
-done
-
-if test -n "$ac_prev"; then
-  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
-  as_fn_error $? "missing argument to $ac_option"
-fi
-
-if test -n "$ac_unrecognized_opts"; then
-  case $enable_option_checking in
-    no) ;;
-    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
-    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
-  esac
-fi
-
-# Check all directory arguments for consistency.
-for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
-		datadir sysconfdir sharedstatedir localstatedir includedir \
-		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir
-do
-  eval ac_val=\$$ac_var
-  # Remove trailing slashes.
-  case $ac_val in
-    */ )
-      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
-      eval $ac_var=\$ac_val;;
-  esac
-  # Be sure to have absolute directory names.
-  case $ac_val in
-    [\\/$]* | ?:[\\/]* )  continue;;
-    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
-  esac
-  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
-done
-
-# There might be people who depend on the old broken behavior: `$host'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
-  if test "x$build_alias" = x; then
-    cross_compiling=maybe
-  elif test "x$build_alias" != "x$host_alias"; then
-    cross_compiling=yes
-  fi
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
-
-test "$silent" = yes && exec 6>/dev/null
-
-
-ac_pwd=`pwd` && test -n "$ac_pwd" &&
-ac_ls_di=`ls -di .` &&
-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  as_fn_error $? "working directory cannot be determined"
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  as_fn_error $? "pwd does not report name of working directory"
-
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
-  ac_srcdir_defaulted=yes
-  # Try the directory containing this script, then the parent directory.
-  ac_confdir=`$as_dirname -- "$as_myself" ||
-$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_myself" : 'X\(//\)[^/]' \| \
-	 X"$as_myself" : 'X\(//\)$' \| \
-	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_myself" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-  srcdir=$ac_confdir
-  if test ! -r "$srcdir/$ac_unique_file"; then
-    srcdir=..
-  fi
-else
-  ac_srcdir_defaulted=no
-fi
-if test ! -r "$srcdir/$ac_unique_file"; then
-  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
-fi
-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
-ac_abs_confdir=`(
-	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
-	pwd)`
-# When building in place, set srcdir=.
-if test "$ac_abs_confdir" = "$ac_pwd"; then
-  srcdir=.
-fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
-  eval ac_env_${ac_var}_set=\${${ac_var}+set}
-  eval ac_env_${ac_var}_value=\$${ac_var}
-  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
-  eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
-
-#
-# Report the --help message.
-#
-if test "$ac_init_help" = "long"; then
-  # Omit some internal or obsolete options to make the list less imposing.
-  # This message is too long to be a string in the A/UX 3.1 sh.
-  cat <<_ACEOF
-\`configure' configures Haskell process package 1.0 to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE.  See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
-  -h, --help              display this help and exit
-      --help=short        display options specific to this package
-      --help=recursive    display the short help of all the included packages
-  -V, --version           display version information and exit
-  -q, --quiet, --silent   do not print \`checking ...' messages
-      --cache-file=FILE   cache test results in FILE [disabled]
-  -C, --config-cache      alias for \`--cache-file=config.cache'
-  -n, --no-create         do not create output files
-      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
-
-Installation directories:
-  --prefix=PREFIX         install architecture-independent files in PREFIX
-                          [$ac_default_prefix]
-  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
-                          [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
-  --bindir=DIR            user executables [EPREFIX/bin]
-  --sbindir=DIR           system admin executables [EPREFIX/sbin]
-  --libexecdir=DIR        program executables [EPREFIX/libexec]
-  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
-  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
-  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
-  --libdir=DIR            object code libraries [EPREFIX/lib]
-  --includedir=DIR        C header files [PREFIX/include]
-  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
-  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
-  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
-  --infodir=DIR           info documentation [DATAROOTDIR/info]
-  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
-  --mandir=DIR            man documentation [DATAROOTDIR/man]
-  --docdir=DIR            documentation root [DATAROOTDIR/doc/process]
-  --htmldir=DIR           html documentation [DOCDIR]
-  --dvidir=DIR            dvi documentation [DOCDIR]
-  --pdfdir=DIR            pdf documentation [DOCDIR]
-  --psdir=DIR             ps documentation [DOCDIR]
-_ACEOF
-
-  cat <<\_ACEOF
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
-  case $ac_init_help in
-     short | recursive ) echo "Configuration of Haskell process package 1.0:";;
-   esac
-  cat <<\_ACEOF
-
-Optional Packages:
-  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
-  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-C compiler
-
-Some influential environment variables:
-  CC          C compiler command
-  CFLAGS      C compiler flags
-  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
-              nonstandard directory <lib dir>
-  LIBS        libraries to pass to the linker, e.g. -l<library>
-  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
-              you have headers in a nonstandard directory <include dir>
-  CPP         C preprocessor
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-Report bugs to <libraries@haskell.org>.
-_ACEOF
-ac_status=$?
-fi
-
-if test "$ac_init_help" = "recursive"; then
-  # If there are subdirs, report their specific --help.
-  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
-    test -d "$ac_dir" ||
-      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
-      continue
-    ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
-  # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
-  case $ac_top_builddir_sub in
-  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
-  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
-  esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
-  .)  # We are building in place.
-    ac_srcdir=.
-    ac_top_srcdir=$ac_top_builddir_sub
-    ac_abs_top_srcdir=$ac_pwd ;;
-  [\\/]* | ?:[\\/]* )  # Absolute name.
-    ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir
-    ac_abs_top_srcdir=$srcdir ;;
-  *) # Relative name.
-    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_build_prefix$srcdir
-    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-    cd "$ac_dir" || { ac_status=$?; continue; }
-    # Check for guested configure.
-    if test -f "$ac_srcdir/configure.gnu"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
-    elif test -f "$ac_srcdir/configure"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure" --help=recursive
-    else
-      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
-    fi || ac_status=$?
-    cd "$ac_pwd" || { ac_status=$?; break; }
-  done
-fi
-
-test -n "$ac_init_help" && exit $ac_status
-if $ac_init_version; then
-  cat <<\_ACEOF
-Haskell process package configure 1.0
-generated by GNU Autoconf 2.69
-
-Copyright (C) 2012 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
-_ACEOF
-  exit
-fi
-
-## ------------------------ ##
-## Autoconf initialization. ##
-## ------------------------ ##
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext
-  if { { ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compile") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_retval=1
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
-
-# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
-# -------------------------------------------
-# Tests whether TYPE exists after having included INCLUDES, setting cache
-# variable VAR accordingly.
-ac_fn_c_check_type ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  eval "$3=no"
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-if (sizeof ($2))
-	 return 0;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-if (sizeof (($2)))
-	    return 0;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
-  eval "$3=yes"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_type
-
-# ac_fn_c_try_cpp LINENO
-# ----------------------
-# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_cpp ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } > conftest.i && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-    ac_retval=1
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_cpp
-
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: program exited with status $ac_status" >&5
-       $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_retval=$ac_status
-fi
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_run
-
-# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists and can be compiled using the include files in
-# INCLUDES, setting the cache variable VAR accordingly.
-ac_fn_c_check_header_compile ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_compile
-
-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists, giving a warning if it cannot be compiled using
-# the include files in INCLUDES and setting the cache variable VAR
-# accordingly.
-ac_fn_c_check_header_mongrel ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if eval \${$3+:} false; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
-$as_echo_n "checking $2 usability... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_header_compiler=yes
-else
-  ac_header_compiler=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
-$as_echo_n "checking $2 presence... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  ac_header_preproc=yes
-else
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
-  yes:no: )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-    ;;
-  no:yes:* )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## ------------------------------------ ##
-## Report this to libraries@haskell.org ##
-## ------------------------------------ ##"
-     ) | sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  eval "$3=\$ac_header_compiler"
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_mongrel
-
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext conftest$ac_exeext
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext && {
-	 test "$cross_compiling" = yes ||
-	 test -x conftest$ac_exeext
-       }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_retval=1
-fi
-  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
-  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
-  # interfere with the next link command; also delete a directory that is
-  # left behind by Apple's compiler.  We do this before executing the actions.
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_link
-
-# ac_fn_c_check_func LINENO FUNC VAR
-# ----------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_c_check_func ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $2 (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $2 ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_func
-
-# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
-# --------------------------------------------
-# Tries to find the compile-time value of EXPR in a program that includes
-# INCLUDES, setting VAR accordingly. Returns whether the value could be
-# computed
-ac_fn_c_compute_int ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if test "$cross_compiling" = yes; then
-    # Depending upon the size, compute the lo and hi bounds.
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) >= 0)];
-test_array [0] = 0;
-return test_array [0];
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_lo=0 ac_mid=0
-  while :; do
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0;
-return test_array [0];
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_hi=$ac_mid; break
-else
-  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
-			if test $ac_lo -le $ac_mid; then
-			  ac_lo= ac_hi=
-			  break
-			fi
-			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  done
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) < 0)];
-test_array [0] = 0;
-return test_array [0];
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_hi=-1 ac_mid=-1
-  while :; do
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) >= $ac_mid)];
-test_array [0] = 0;
-return test_array [0];
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_lo=$ac_mid; break
-else
-  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
-			if test $ac_mid -le $ac_hi; then
-			  ac_lo= ac_hi=
-			  break
-			fi
-			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  done
-else
-  ac_lo= ac_hi=
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-# Binary search between lo and hi bounds.
-while test "x$ac_lo" != "x$ac_hi"; do
-  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0;
-return test_array [0];
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_hi=$ac_mid
-else
-  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-case $ac_lo in #((
-?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
-'') ac_retval=1 ;;
-esac
-  else
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-static long int longval () { return $2; }
-static unsigned long int ulongval () { return $2; }
-#include <stdio.h>
-#include <stdlib.h>
-int
-main ()
-{
-
-  FILE *f = fopen ("conftest.val", "w");
-  if (! f)
-    return 1;
-  if (($2) < 0)
-    {
-      long int i = longval ();
-      if (i != ($2))
-	return 1;
-      fprintf (f, "%ld", i);
-    }
-  else
-    {
-      unsigned long int i = ulongval ();
-      if (i != ($2))
-	return 1;
-      fprintf (f, "%lu", i);
-    }
-  /* Do not output a trailing newline, as this causes \r\n confusion
-     on some platforms.  */
-  return ferror (f) || fclose (f) != 0;
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
-else
-  ac_retval=1
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-rm -f conftest.val
-
-  fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_compute_int
-cat >config.log <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-
-It was created by Haskell process package $as_me 1.0, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
-
-  $ $0 $@
-
-_ACEOF
-exec 5>>config.log
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
-
-/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
-/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
-/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
-/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
-/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    $as_echo "PATH: $as_dir"
-  done
-IFS=$as_save_IFS
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
-  for ac_arg
-  do
-    case $ac_arg in
-    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
-    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-    | -silent | --silent | --silen | --sile | --sil)
-      continue ;;
-    *\'*)
-      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
-    esac
-    case $ac_pass in
-    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
-    2)
-      as_fn_append ac_configure_args1 " '$ac_arg'"
-      if test $ac_must_keep_next = true; then
-	ac_must_keep_next=false # Got value, back to normal.
-      else
-	case $ac_arg in
-	  *=* | --config-cache | -C | -disable-* | --disable-* \
-	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
-	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
-	  | -with-* | --with-* | -without-* | --without-* | --x)
-	    case "$ac_configure_args0 " in
-	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
-	    esac
-	    ;;
-	  -* ) ac_must_keep_next=true ;;
-	esac
-      fi
-      as_fn_append ac_configure_args " '$ac_arg'"
-      ;;
-    esac
-  done
-done
-{ ac_configure_args0=; unset ac_configure_args0;}
-{ ac_configure_args1=; unset ac_configure_args1;}
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log.  We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
-trap 'exit_status=$?
-  # Save into config.log some information that might help in debugging.
-  {
-    echo
-
-    $as_echo "## ---------------- ##
-## Cache variables. ##
-## ---------------- ##"
-    echo
-    # The following way of writing the cache mishandles newlines in values,
-(
-  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
-      *) { eval $ac_var=; unset $ac_var;} ;;
-      esac ;;
-    esac
-  done
-  (set) 2>&1 |
-    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
-      sed -n \
-	"s/'\''/'\''\\\\'\'''\''/g;
-	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
-      ;; #(
-    *)
-      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
-      ;;
-    esac |
-    sort
-)
-    echo
-
-    $as_echo "## ----------------- ##
-## Output variables. ##
-## ----------------- ##"
-    echo
-    for ac_var in $ac_subst_vars
-    do
-      eval ac_val=\$$ac_var
-      case $ac_val in
-      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-      esac
-      $as_echo "$ac_var='\''$ac_val'\''"
-    done | sort
-    echo
-
-    if test -n "$ac_subst_files"; then
-      $as_echo "## ------------------- ##
-## File substitutions. ##
-## ------------------- ##"
-      echo
-      for ac_var in $ac_subst_files
-      do
-	eval ac_val=\$$ac_var
-	case $ac_val in
-	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
-	esac
-	$as_echo "$ac_var='\''$ac_val'\''"
-      done | sort
-      echo
-    fi
-
-    if test -s confdefs.h; then
-      $as_echo "## ----------- ##
-## confdefs.h. ##
-## ----------- ##"
-      echo
-      cat confdefs.h
-      echo
-    fi
-    test "$ac_signal" != 0 &&
-      $as_echo "$as_me: caught signal $ac_signal"
-    $as_echo "$as_me: exit $exit_status"
-  } >&5
-  rm -f core *.core core.conftest.* &&
-    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
-    exit $exit_status
-' 0
-for ac_signal in 1 2 13 15; do
-  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
-
-$as_echo "/* confdefs.h */" > confdefs.h
-
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_URL "$PACKAGE_URL"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer an explicitly selected file to automatically selected ones.
-ac_site_file1=NONE
-ac_site_file2=NONE
-if test -n "$CONFIG_SITE"; then
-  # We do not want a PATH search for config.site.
-  case $CONFIG_SITE in #((
-    -*)  ac_site_file1=./$CONFIG_SITE;;
-    */*) ac_site_file1=$CONFIG_SITE;;
-    *)   ac_site_file1=./$CONFIG_SITE;;
-  esac
-elif test "x$prefix" != xNONE; then
-  ac_site_file1=$prefix/share/config.site
-  ac_site_file2=$prefix/etc/config.site
-else
-  ac_site_file1=$ac_default_prefix/share/config.site
-  ac_site_file2=$ac_default_prefix/etc/config.site
-fi
-for ac_site_file in "$ac_site_file1" "$ac_site_file2"
-do
-  test "x$ac_site_file" = xNONE && continue
-  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
-$as_echo "$as_me: loading site script $ac_site_file" >&6;}
-    sed 's/^/| /' "$ac_site_file" >&5
-    . "$ac_site_file" \
-      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5; }
-  fi
-done
-
-if test -r "$cache_file"; then
-  # Some versions of bash will fail to source /dev/null (special files
-  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
-  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
-$as_echo "$as_me: loading cache $cache_file" >&6;}
-    case $cache_file in
-      [\\/]* | ?:[\\/]* ) . "$cache_file";;
-      *)                      . "./$cache_file";;
-    esac
-  fi
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
-$as_echo "$as_me: creating cache $cache_file" >&6;}
-  >$cache_file
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
-  eval ac_old_set=\$ac_cv_env_${ac_var}_set
-  eval ac_new_set=\$ac_env_${ac_var}_set
-  eval ac_old_val=\$ac_cv_env_${ac_var}_value
-  eval ac_new_val=\$ac_env_${ac_var}_value
-  case $ac_old_set,$ac_new_set in
-    set,)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,set)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,);;
-    *)
-      if test "x$ac_old_val" != "x$ac_new_val"; then
-	# differences in whitespace do not lead to failure.
-	ac_old_val_w=`echo x $ac_old_val`
-	ac_new_val_w=`echo x $ac_new_val`
-	if test "$ac_old_val_w" != "$ac_new_val_w"; then
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
-	  ac_cache_corrupted=:
-	else
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
-	  eval $ac_var=\$ac_old_val
-	fi
-	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
-$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
-	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
-$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
-      fi;;
-  esac
-  # Pass precious variables to config.status.
-  if test "$ac_new_set" = set; then
-    case $ac_new_val in
-    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
-    *) ac_arg=$ac_var=$ac_new_val ;;
-    esac
-    case " $ac_configure_args " in
-      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
-      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
-    esac
-  fi
-done
-if $ac_cache_corrupted; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
-fi
-## -------------------- ##
-## Main body of script. ##
-## -------------------- ##
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-# Safety check: Ensure that we are in the correct source directory.
-
-
-ac_config_headers="$ac_config_headers include/HsProcessConfig.h"
-
-
-
-# Check whether --with-cc was given.
-if test "${with_cc+set}" = set; then :
-  withval=$with_cc; CC=$withval
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
-          if test -n "$ac_tool_prefix"; then
-    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  fi
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl.exe
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-    test -n "$CC" && break
-  done
-fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl.exe
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$ac_ct_CC" && break
-done
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    CC=$ac_ct_CC
-  fi
-fi
-
-fi
-
-
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
-
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
-  { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    sed '10a\
-... rest of stderr output deleted ...
-         10q' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-  fi
-  rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-done
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-
-# The possible output files:
-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
-
-ac_rmfiles=
-for ac_file in $ac_files
-do
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
-    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
-  esac
-done
-rm -f $ac_rmfiles
-
-if { { ac_try="$ac_link_default"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link_default") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile.  We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
-	;;
-    [ab].out )
-	# We found the default executable, but exeext='' is most
-	# certainly right.
-	break;;
-    *.* )
-	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
-	then :; else
-	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-	fi
-	# We set ac_cv_exeext here because the later test for it is not
-	# safe: cross compilers may not add the suffix if given an `-o'
-	# argument, so we may need to know it at that point already.
-	# Even if this section looks crufty: it has the advantage of
-	# actually working.
-	break;;
-    * )
-	break;;
-  esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
-else
-  ac_file=''
-fi
-if test -z "$ac_file"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-$as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
-ac_exeext=$ac_cv_exeext
-
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
-if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
-    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-	  break;;
-    * ) break;;
-  esac
-done
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdio.h>
-int
-main ()
-{
-FILE *f = fopen ("conftest.out", "w");
- return ferror (f) || fclose (f) != 0;
-
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files="$ac_clean_files conftest.out"
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-if test "$cross_compiling" != yes; then
-  { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-  if { ac_try='./conftest$ac_cv_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-	cross_compiling=yes
-    else
-	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5; }
-    fi
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
-
-rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if ${ac_cv_objext+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { { ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compile") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  for ac_file in conftest.o conftest.obj conftest.*; do
-  test -f "$ac_file" || continue;
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
-    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
-       break;;
-  esac
-done
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_compiler_gnu=yes
-else
-  ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
-  GCC=yes
-else
-  GCC=
-fi
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_save_c_werror_flag=$ac_c_werror_flag
-   ac_c_werror_flag=yes
-   ac_cv_prog_cc_g=no
-   CFLAGS="-g"
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-else
-  CFLAGS=""
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
-  ac_c_werror_flag=$ac_save_c_werror_flag
-	 CFLAGS="-g"
-	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_c89=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
-  xno)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if ${ac_cv_prog_CPP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-		     Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-  break
-fi
-
-    done
-    ac_cv_prog_CPP=$CPP
-
-fi
-  CPP=$ac_cv_prog_CPP
-else
-  ac_cv_prog_CPP=$CPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-		     Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if ${ac_cv_path_GREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -z "$GREP"; then
-  ac_path_GREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in grep ggrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_GREP" || continue
-# Check for GNU ac_path_GREP and select it if it is found.
-  # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'GREP' >> "conftest.nl"
-    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_GREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_GREP="$ac_path_GREP"
-      ac_path_GREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-      $ac_path_GREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_GREP"; then
-    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
-  fi
-else
-  ac_cv_path_GREP=$GREP
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if ${ac_cv_path_EGREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
-   then ac_cv_path_EGREP="$GREP -E"
-   else
-     if test -z "$EGREP"; then
-  ac_path_EGREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in egrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_EGREP" || continue
-# Check for GNU ac_path_EGREP and select it if it is found.
-  # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'EGREP' >> "conftest.nl"
-    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_EGREP="$ac_path_EGREP"
-      ac_path_EGREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-      $ac_path_EGREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_EGREP"; then
-    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
-  fi
-else
-  ac_cv_path_EGREP=$EGREP
-fi
-
-   fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_stdc=yes
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then :
-  :
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-		   (('a' <= (c) && (c) <= 'i') \
-		     || ('j' <= (c) && (c) <= 'r') \
-		     || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-	|| toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
-		  inttypes.h stdint.h unistd.h
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
-if test "x$ac_cv_type_pid_t" = xyes; then :
-
-else
-
-cat >>confdefs.h <<_ACEOF
-#define pid_t int
-_ACEOF
-
-fi
-
-for ac_header in vfork.h
-do :
-  ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
-if test "x$ac_cv_header_vfork_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_VFORK_H 1
-_ACEOF
-
-fi
-
-done
-
-for ac_func in fork vfork
-do :
-  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-if test "x$ac_cv_func_fork" = xyes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
-$as_echo_n "checking for working fork... " >&6; }
-if ${ac_cv_func_fork_works+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "$cross_compiling" = yes; then :
-  ac_cv_func_fork_works=cross
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
-{
-
-	  /* By Ruediger Kuhlmann. */
-	  return fork () < 0;
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  ac_cv_func_fork_works=yes
-else
-  ac_cv_func_fork_works=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
-$as_echo "$ac_cv_func_fork_works" >&6; }
-
-else
-  ac_cv_func_fork_works=$ac_cv_func_fork
-fi
-if test "x$ac_cv_func_fork_works" = xcross; then
-  case $host in
-    *-*-amigaos* | *-*-msdosdjgpp*)
-      # Override, as these systems have only a dummy fork() stub
-      ac_cv_func_fork_works=no
-      ;;
-    *)
-      ac_cv_func_fork_works=yes
-      ;;
-  esac
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
-$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
-fi
-ac_cv_func_vfork_works=$ac_cv_func_vfork
-if test "x$ac_cv_func_vfork" = xyes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
-$as_echo_n "checking for working vfork... " >&6; }
-if ${ac_cv_func_vfork_works+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "$cross_compiling" = yes; then :
-  ac_cv_func_vfork_works=cross
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-/* Thanks to Paul Eggert for this test.  */
-$ac_includes_default
-#include <sys/wait.h>
-#ifdef HAVE_VFORK_H
-# include <vfork.h>
-#endif
-/* On some sparc systems, changes by the child to local and incoming
-   argument registers are propagated back to the parent.  The compiler
-   is told about this with #include <vfork.h>, but some compilers
-   (e.g. gcc -O) don't grok <vfork.h>.  Test for this by using a
-   static variable whose address is put into a register that is
-   clobbered by the vfork.  */
-static void
-#ifdef __cplusplus
-sparc_address_test (int arg)
-# else
-sparc_address_test (arg) int arg;
-#endif
-{
-  static pid_t child;
-  if (!child) {
-    child = vfork ();
-    if (child < 0) {
-      perror ("vfork");
-      _exit(2);
-    }
-    if (!child) {
-      arg = getpid();
-      write(-1, "", 0);
-      _exit (arg);
-    }
-  }
-}
-
-int
-main ()
-{
-  pid_t parent = getpid ();
-  pid_t child;
-
-  sparc_address_test (0);
-
-  child = vfork ();
-
-  if (child == 0) {
-    /* Here is another test for sparc vfork register problems.  This
-       test uses lots of local variables, at least as many local
-       variables as main has allocated so far including compiler
-       temporaries.  4 locals are enough for gcc 1.40.3 on a Solaris
-       4.1.3 sparc, but we use 8 to be safe.  A buggy compiler should
-       reuse the register of parent for one of the local variables,
-       since it will think that parent can't possibly be used any more
-       in this routine.  Assigning to the local variable will thus
-       munge parent in the parent process.  */
-    pid_t
-      p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
-      p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
-    /* Convince the compiler that p..p7 are live; otherwise, it might
-       use the same hardware register for all 8 local variables.  */
-    if (p != p1 || p != p2 || p != p3 || p != p4
-	|| p != p5 || p != p6 || p != p7)
-      _exit(1);
-
-    /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
-       from child file descriptors.  If the child closes a descriptor
-       before it execs or exits, this munges the parent's descriptor
-       as well.  Test for this by closing stdout in the child.  */
-    _exit(close(fileno(stdout)) != 0);
-  } else {
-    int status;
-    struct stat st;
-
-    while (wait(&status) != child)
-      ;
-    return (
-	 /* Was there some problem with vforking?  */
-	 child < 0
-
-	 /* Did the child fail?  (This shouldn't happen.)  */
-	 || status
-
-	 /* Did the vfork/compiler bug occur?  */
-	 || parent != getpid()
-
-	 /* Did the file descriptor bug occur?  */
-	 || fstat(fileno(stdout), &st) != 0
-	 );
-  }
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  ac_cv_func_vfork_works=yes
-else
-  ac_cv_func_vfork_works=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
-$as_echo "$ac_cv_func_vfork_works" >&6; }
-
-fi;
-if test "x$ac_cv_func_fork_works" = xcross; then
-  ac_cv_func_vfork_works=$ac_cv_func_vfork
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
-$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
-fi
-
-if test "x$ac_cv_func_vfork_works" = xyes; then
-
-$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h
-
-else
-
-$as_echo "#define vfork fork" >>confdefs.h
-
-fi
-if test "x$ac_cv_func_fork_works" = xyes; then
-
-$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
-
-fi
-
-
-# check for specific header (.h) files that we are interested in
-for ac_header in signal.h sys/wait.h fcntl.h
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-for ac_func in setitimer sysconf
-do :
-  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
-
-for fp_const_name in SIG_DFL SIG_IGN
-do
-as_fp_Cache=`$as_echo "fp_cv_const_$fp_const_name" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking value of $fp_const_name" >&5
-$as_echo_n "checking value of $fp_const_name... " >&6; }
-if eval \${$as_fp_Cache+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "$fp_const_name" "fp_check_const_result"        "$ac_includes_default"; then :
-
-else
-  fp_check_const_result='-1'
-fi
-
-
-eval "$as_fp_Cache=\$fp_check_const_result"
-fi
-eval ac_res=\$$as_fp_Cache
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-cat >>confdefs.h <<_ACEOF
-#define `$as_echo "CONST_$fp_const_name" | $as_tr_cpp` `eval 'as_val=${'$as_fp_Cache'};$as_echo "$as_val"'`
-_ACEOF
-
-done
-
-
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems.  If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(
-  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
-    eval ac_val=\$$ac_var
-    case $ac_val in #(
-    *${as_nl}*)
-      case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
-      esac
-      case $ac_var in #(
-      _ | IFS | as_nl) ;; #(
-      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
-      *) { eval $ac_var=; unset $ac_var;} ;;
-      esac ;;
-    esac
-  done
-
-  (set) 2>&1 |
-    case $as_nl`(ac_space=' '; set) 2>&1` in #(
-    *${as_nl}ac_space=\ *)
-      # `set' does not quote correctly, so add quotes: double-quote
-      # substitution turns \\\\ into \\, and sed turns \\ into \.
-      sed -n \
-	"s/'/'\\\\''/g;
-	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
-      ;; #(
-    *)
-      # `set' quotes correctly as required by POSIX, so do not add quotes.
-      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
-      ;;
-    esac |
-    sort
-) |
-  sed '
-     /^ac_cv_env_/b end
-     t clear
-     :clear
-     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
-     t end
-     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
-     :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
-  if test -w "$cache_file"; then
-    if test "x$cache_file" != "x/dev/null"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
-$as_echo "$as_me: updating cache $cache_file" >&6;}
-      if test ! -f "$cache_file" || test -h "$cache_file"; then
-	cat confcache >"$cache_file"
-      else
-        case $cache_file in #(
-        */* | ?:*)
-	  mv -f confcache "$cache_file"$$ &&
-	  mv -f "$cache_file"$$ "$cache_file" ;; #(
-        *)
-	  mv -f confcache "$cache_file" ;;
-	esac
-      fi
-    fi
-  else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
-  fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-DEFS=-DHAVE_CONFIG_H
-
-ac_libobjs=
-ac_ltlibobjs=
-U=
-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
-  # 1. Remove the extension, and $U if already installed.
-  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
-  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
-  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
-  #    will be set to the directory where LIBOBJS objects are built.
-  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
-  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
-
-: "${CONFIG_STATUS=./config.status}"
-ac_write_fail=0
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
-as_write_fail=0
-cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate the current configuration.
-# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-
-SHELL=\${CONFIG_SHELL-$SHELL}
-export SHELL
-_ASEOF
-cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
-  emulate sh
-  NULLCMD=:
-  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in #(
-  *posix*) :
-    set -o posix ;; #(
-  *) :
-     ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-	expr "X$arg" : "X\\(.*\\)$as_nl";
-	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  PATH_SEPARATOR=:
-  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
-    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
-      PATH_SEPARATOR=';'
-  }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""	$as_nl"
-
-# Find who we are.  Look in the path if we contain no directory separator.
-as_myself=
-case $0 in #((
-  *[\\/]* ) as_myself=$0 ;;
-  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-  done
-IFS=$as_save_IFS
-
-     ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
-  as_myself=$0
-fi
-if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
-as_fn_error ()
-{
-  as_status=$1; test $as_status -eq 0 && as_status=1
-  if test "$4"; then
-    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
-  fi
-  $as_echo "$as_me: error: $2" >&2
-  as_fn_exit $as_status
-} # as_fn_error
-
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
-  return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
-  set +e
-  as_fn_set_status $1
-  exit $1
-} # as_fn_exit
-
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
-  { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
-  eval 'as_fn_append ()
-  {
-    eval $1+=\$2
-  }'
-else
-  as_fn_append ()
-  {
-    eval $1=\$$1\$2
-  }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
-  eval 'as_fn_arith ()
-  {
-    as_val=$(( $* ))
-  }'
-else
-  as_fn_arith ()
-  {
-    as_val=`expr "$@" || test $? -eq 1`
-  }
-fi # as_fn_arith
-
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
-  as_basename=basename
-else
-  as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
-	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
-  case `echo 'xy\c'` in
-  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
-  xy)  ECHO_C='\c';;
-  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
-       ECHO_T='	';;
-  esac;;
-*)
-  ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
-  rm -f conf$$.dir/conf$$.file
-else
-  rm -f conf$$.dir
-  mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
-  if ln -s conf$$.file conf$$ 2>/dev/null; then
-    as_ln_s='ln -s'
-    # ... but there are two gotchas:
-    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -pR'.
-    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -pR'
-  elif ln conf$$.file conf$$ 2>/dev/null; then
-    as_ln_s=ln
-  else
-    as_ln_s='cp -pR'
-  fi
-else
-  as_ln_s='cp -pR'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
-  case $as_dir in #(
-  -*) as_dir=./$as_dir;;
-  esac
-  test -d "$as_dir" || eval $as_mkdir_p || {
-    as_dirs=
-    while :; do
-      case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
-      *) as_qdir=$as_dir;;
-      esac
-      as_dirs="'$as_qdir' $as_dirs"
-      as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_dir" : 'X\(//\)[^/]' \| \
-	 X"$as_dir" : 'X\(//\)$' \| \
-	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-      test -d "$as_dir" && break
-    done
-    test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-if mkdir -p . 2>/dev/null; then
-  as_mkdir_p='mkdir -p "$as_dir"'
-else
-  test -d ./-p && rmdir ./-p
-  as_mkdir_p=false
-fi
-
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
-  test -f "$1" && test -x "$1"
-} # as_fn_executable_p
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-exec 6>&1
-## ----------------------------------- ##
-## Main body of $CONFIG_STATUS script. ##
-## ----------------------------------- ##
-_ASEOF
-test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# Save the log message, to keep $0 and so on meaningful, and to
-# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.
-ac_log="
-This file was extended by Haskell process package $as_me 1.0, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
-
-  CONFIG_FILES    = $CONFIG_FILES
-  CONFIG_HEADERS  = $CONFIG_HEADERS
-  CONFIG_LINKS    = $CONFIG_LINKS
-  CONFIG_COMMANDS = $CONFIG_COMMANDS
-  $ $0 $@
-
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
-_ACEOF
-
-
-case $ac_config_headers in *"
-"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
-esac
-
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-# Files that config.status was made for.
-config_headers="$ac_config_headers"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-ac_cs_usage="\
-\`$as_me' instantiates files and other configuration actions
-from templates according to the current configuration.  Unless the files
-and actions are specified as TAGs, all are instantiated by default.
-
-Usage: $0 [OPTION]... [TAG]...
-
-  -h, --help       print this help, then exit
-  -V, --version    print version number and configuration settings, then exit
-      --config     print configuration, then exit
-  -q, --quiet, --silent
-                   do not print progress messages
-  -d, --debug      don't remove temporary files
-      --recheck    update $as_me by reconfiguring in the same conditions
-      --header=FILE[:TEMPLATE]
-                   instantiate the configuration header FILE
-
-Configuration headers:
-$config_headers
-
-Report bugs to <libraries@haskell.org>."
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
-ac_cs_version="\\
-Haskell process package config.status 1.0
-configured by $0, generated by GNU Autoconf 2.69,
-  with options \\"\$ac_cs_config\\"
-
-Copyright (C) 2012 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
-test -n "\$AWK" || AWK=awk
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# The default lists apply if the user does not specify any file.
-ac_need_defaults=:
-while test $# != 0
-do
-  case $1 in
-  --*=?*)
-    ac_option=`expr "X$1" : 'X\([^=]*\)='`
-    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
-    ac_shift=:
-    ;;
-  --*=)
-    ac_option=`expr "X$1" : 'X\([^=]*\)='`
-    ac_optarg=
-    ac_shift=:
-    ;;
-  *)
-    ac_option=$1
-    ac_optarg=$2
-    ac_shift=shift
-    ;;
-  esac
-
-  case $ac_option in
-  # Handling of the options.
-  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
-    ac_cs_recheck=: ;;
-  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
-    $as_echo "$ac_cs_version"; exit ;;
-  --config | --confi | --conf | --con | --co | --c )
-    $as_echo "$ac_cs_config"; exit ;;
-  --debug | --debu | --deb | --de | --d | -d )
-    debug=: ;;
-  --header | --heade | --head | --hea )
-    $ac_shift
-    case $ac_optarg in
-    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
-    esac
-    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
-    ac_need_defaults=false;;
-  --he | --h)
-    # Conflict between --help and --header
-    as_fn_error $? "ambiguous option: \`$1'
-Try \`$0 --help' for more information.";;
-  --help | --hel | -h )
-    $as_echo "$ac_cs_usage"; exit ;;
-  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-  | -silent | --silent | --silen | --sile | --sil | --si | --s)
-    ac_cs_silent=: ;;
-
-  # This is an error.
-  -*) as_fn_error $? "unrecognized option: \`$1'
-Try \`$0 --help' for more information." ;;
-
-  *) as_fn_append ac_config_targets " $1"
-     ac_need_defaults=false ;;
-
-  esac
-  shift
-done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
-  exec 6>/dev/null
-  ac_configure_extra_args="$ac_configure_extra_args --silent"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-if \$ac_cs_recheck; then
-  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
-  shift
-  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
-  CONFIG_SHELL='$SHELL'
-  export CONFIG_SHELL
-  exec "\$@"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-exec 5>>config.log
-{
-  echo
-  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
-  $as_echo "$ac_log"
-} >&5
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-
-# Handling of arguments.
-for ac_config_target in $ac_config_targets
-do
-  case $ac_config_target in
-    "include/HsProcessConfig.h") CONFIG_HEADERS="$CONFIG_HEADERS include/HsProcessConfig.h" ;;
-
-  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
-  esac
-done
-
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used.  Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
-  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
-fi
-
-# Have a temporary directory for convenience.  Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
-$debug ||
-{
-  tmp= ac_tmp=
-  trap 'exit_status=$?
-  : "${ac_tmp:=$tmp}"
-  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
-' 0
-  trap 'as_fn_exit 1' 1 2 13 15
-}
-# Create a (secure) tmp directory for tmp files.
-
-{
-  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
-  test -d "$tmp"
-}  ||
-{
-  tmp=./conf$$-$RANDOM
-  (umask 077 && mkdir "$tmp")
-} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
-ac_tmp=$tmp
-
-# Set up the scripts for CONFIG_HEADERS section.
-# No need to generate them if there are no CONFIG_HEADERS.
-# This happens for instance with `./config.status Makefile'.
-if test -n "$CONFIG_HEADERS"; then
-cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
-BEGIN {
-_ACEOF
-
-# Transform confdefs.h into an awk script `defines.awk', embedded as
-# here-document in config.status, that substitutes the proper values into
-# config.h.in to produce config.h.
-
-# Create a delimiter string that does not exist in confdefs.h, to ease
-# handling of long lines.
-ac_delim='%!_!# '
-for ac_last_try in false false :; do
-  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
-  if test -z "$ac_tt"; then
-    break
-  elif $ac_last_try; then
-    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
-  else
-    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
-  fi
-done
-
-# For the awk script, D is an array of macro values keyed by name,
-# likewise P contains macro parameters if any.  Preserve backslash
-# newline sequences.
-
-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
-sed -n '
-s/.\{148\}/&'"$ac_delim"'/g
-t rset
-:rset
-s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
-t def
-d
-:def
-s/\\$//
-t bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3"/p
-s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
-d
-:bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3\\\\\\n"\\/p
-t cont
-s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
-t cont
-d
-:cont
-n
-s/.\{148\}/&'"$ac_delim"'/g
-t clear
-:clear
-s/\\$//
-t bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/"/p
-d
-:bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
-b cont
-' <confdefs.h | sed '
-s/'"$ac_delim"'/"\\\
-"/g' >>$CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-  for (key in D) D_is_set[key] = 1
-  FS = ""
-}
-/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
-  line = \$ 0
-  split(line, arg, " ")
-  if (arg[1] == "#") {
-    defundef = arg[2]
-    mac1 = arg[3]
-  } else {
-    defundef = substr(arg[1], 2)
-    mac1 = arg[2]
-  }
-  split(mac1, mac2, "(") #)
-  macro = mac2[1]
-  prefix = substr(line, 1, index(line, defundef) - 1)
-  if (D_is_set[macro]) {
-    # Preserve the white space surrounding the "#".
-    print prefix "define", macro P[macro] D[macro]
-    next
-  } else {
-    # Replace #undef with comments.  This is necessary, for example,
-    # in the case of _POSIX_SOURCE, which is predefined and required
-    # on some systems where configure will not decide to define it.
-    if (defundef == "undef") {
-      print "/*", prefix defundef, macro, "*/"
-      next
-    }
-  }
-}
-{ print }
-_ACAWK
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
-fi # test -n "$CONFIG_HEADERS"
-
-
-eval set X "    :H $CONFIG_HEADERS    "
-shift
-for ac_tag
-do
-  case $ac_tag in
-  :[FHLC]) ac_mode=$ac_tag; continue;;
-  esac
-  case $ac_mode$ac_tag in
-  :[FHL]*:*);;
-  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
-  :[FH]-) ac_tag=-:-;;
-  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
-  esac
-  ac_save_IFS=$IFS
-  IFS=:
-  set x $ac_tag
-  IFS=$ac_save_IFS
-  shift
-  ac_file=$1
-  shift
-
-  case $ac_mode in
-  :L) ac_source=$1;;
-  :[FH])
-    ac_file_inputs=
-    for ac_f
-    do
-      case $ac_f in
-      -) ac_f="$ac_tmp/stdin";;
-      *) # Look for the file first in the build tree, then in the source tree
-	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
-	 # because $ac_f cannot contain `:'.
-	 test -f "$ac_f" ||
-	   case $ac_f in
-	   [\\/$]*) false;;
-	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
-	   esac ||
-	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
-      esac
-      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
-      as_fn_append ac_file_inputs " '$ac_f'"
-    done
-
-    # Let's still pretend it is `configure' which instantiates (i.e., don't
-    # use $as_me), people would be surprised to read:
-    #    /* config.h.  Generated by config.status.  */
-    configure_input='Generated from '`
-	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
-	`' by configure.'
-    if test x"$ac_file" != x-; then
-      configure_input="$ac_file.  $configure_input"
-      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
-$as_echo "$as_me: creating $ac_file" >&6;}
-    fi
-    # Neutralize special characters interpreted by sed in replacement strings.
-    case $configure_input in #(
-    *\&* | *\|* | *\\* )
-       ac_sed_conf_input=`$as_echo "$configure_input" |
-       sed 's/[\\\\&|]/\\\\&/g'`;; #(
-    *) ac_sed_conf_input=$configure_input;;
-    esac
-
-    case $ac_tag in
-    *:-:* | *:-) cat >"$ac_tmp/stdin" \
-      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
-    esac
-    ;;
-  esac
-
-  ac_dir=`$as_dirname -- "$ac_file" ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$ac_file" : 'X\(//\)[^/]' \| \
-	 X"$ac_file" : 'X\(//\)$' \| \
-	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$ac_file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-  as_dir="$ac_dir"; as_fn_mkdir_p
-  ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
-  # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
-  case $ac_top_builddir_sub in
-  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
-  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
-  esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
-  .)  # We are building in place.
-    ac_srcdir=.
-    ac_top_srcdir=$ac_top_builddir_sub
-    ac_abs_top_srcdir=$ac_pwd ;;
-  [\\/]* | ?:[\\/]* )  # Absolute name.
-    ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir
-    ac_abs_top_srcdir=$srcdir ;;
-  *) # Relative name.
-    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_build_prefix$srcdir
-    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-
-  case $ac_mode in
-
-  :H)
-  #
-  # CONFIG_HEADER
-  #
-  if test x"$ac_file" != x-; then
-    {
-      $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
-    } >"$ac_tmp/config.h" \
-      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
-    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
-$as_echo "$as_me: $ac_file is unchanged" >&6;}
-    else
-      rm -f "$ac_file"
-      mv "$ac_tmp/config.h" "$ac_file" \
-	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
-    fi
-  else
-    $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
-      || as_fn_error $? "could not create -" "$LINENO" 5
-  fi
- ;;
-
-
-  esac
-
-done # for ac_tag
-
-
-as_fn_exit 0
-_ACEOF
-ac_clean_files=$ac_clean_files_save
-
-test $ac_write_fail = 0 ||
-  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded.  So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status.  When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
-  ac_cs_success=:
-  ac_config_status_args=
-  test "$silent" = yes &&
-    ac_config_status_args="$ac_config_status_args --quiet"
-  exec 5>/dev/null
-  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
-  exec 5>>config.log
-  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
-  # would make configure fail if this is the last instruction.
-  $ac_cs_success || as_fn_exit 1
-fi
-if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
-fi
+# Generated by GNU Autoconf 2.71 for Haskell process package 1.0.
+#
+# Report bugs to <libraries@haskell.org>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
+# Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else $as_nop
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
+as_nl='
+'
+export as_nl
+IFS=" ""	$as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
+
+# The user is always right.
+if ${PATH_SEPARATOR+false} :; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="as_nop=:
+if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else \$as_nop
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" )
+then :
+
+else \$as_nop
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+blah=\$(echo \$(echo blah))
+test x\"\$blah\" = xblah || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null
+then :
+  as_have_required=yes
+else $as_nop
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
+then :
+
+else $as_nop
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null
+then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+IFS=$as_save_IFS
+if $as_found
+then :
+
+else $as_nop
+  if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi
+fi
+
+
+      if test "x$CONFIG_SHELL" != x
+then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno
+then :
+  printf "%s\n" "$0: This script requires a shell more modern than all"
+  printf "%s\n" "$0: the shells that I found on your system."
+  if test ${ZSH_VERSION+y} ; then
+    printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and
+$0: libraries@haskell.org about your system, including any
+$0: error possibly output before this message. Then install
+$0: a modern shell, or manually run the script under such a
+$0: shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else $as_nop
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else $as_nop
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  printf "%s\n" "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='Haskell process package'
+PACKAGE_TARNAME='process'
+PACKAGE_VERSION='1.0'
+PACKAGE_STRING='Haskell process package 1.0'
+PACKAGE_BUGREPORT='libraries@haskell.org'
+PACKAGE_URL=''
+
+ac_unique_file="include/runProcess.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stddef.h>
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_header_c_list=
+ac_func_c_list=
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+runstatedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir runstatedir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures Haskell process package 1.0 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/process]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of Haskell process package 1.0:";;
+   esac
+  cat <<\_ACEOF
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <libraries@haskell.org>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for configure.gnu first; this name is used for a wrapper for
+    # Metaconfig's "Configure" on case-insensitive file systems.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+Haskell process package configure 1.0
+generated by GNU Autoconf 2.71
+
+Copyright (C) 2021 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest.beam
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext
+then :
+  ac_retval=0
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main (void)
+{
+if (sizeof ($2))
+	 return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main (void)
+{
+if (sizeof (($2)))
+	    return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+else $as_nop
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  eval "$3=yes"
+else $as_nop
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }
+then :
+  ac_retval=0
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+   which can conflict with char $2 (); below.  */
+
+#include <limits.h>
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main (void)
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+  eval "$3=yes"
+else $as_nop
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that
+# executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+then :
+  ac_retval=0
+else $as_nop
+  printf "%s\n" "$as_me: program exited with status $ac_status" >&5
+       printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR
+# ------------------------------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR.
+ac_fn_check_decl ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  as_decl_name=`echo $2|sed 's/ *(.*//'`
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+printf %s "checking whether $as_decl_name is declared... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+  eval ac_save_FLAGS=\$$6
+  as_fn_append $6 " $5"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main (void)
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+  (void) $as_decl_use;
+#else
+  (void) $as_decl_name;
+#endif
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  eval "$3=yes"
+else $as_nop
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+  eval $6=\$ac_save_FLAGS
+
+fi
+eval ac_res=\$$3
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_check_decl
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main (void)
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main (void)
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_hi=$ac_mid; break
+else $as_nop
+  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+			if test $ac_lo -le $ac_mid; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+  done
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main (void)
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main (void)
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_lo=$ac_mid; break
+else $as_nop
+  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+			if test $ac_mid -le $ac_hi; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+  done
+else $as_nop
+  ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main (void)
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_hi=$ac_mid
+else $as_nop
+  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+  else
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+static long int longval (void) { return $2; }
+static unsigned long int ulongval (void) { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main (void)
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (($2) < 0)
+    {
+      long int i = longval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%ld", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%lu", i);
+    }
+  /* Do not output a trailing newline, as this causes \r\n confusion
+     on some platforms.  */
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"
+then :
+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else $as_nop
+  ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+  fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+ac_configure_args_raw=
+for ac_arg
+do
+  case $ac_arg in
+  *\'*)
+    ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  as_fn_append ac_configure_args_raw " '$ac_arg'"
+done
+
+case $ac_configure_args_raw in
+  *$as_nl*)
+    ac_safe_unquote= ;;
+  *)
+    ac_unsafe_z='|&;<>()$`\\"*?[ ''	' # This string ends in space, tab.
+    ac_unsafe_a="$ac_unsafe_z#~"
+    ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"
+    ac_configure_args_raw=`      printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;
+esac
+
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by Haskell process package $as_me 1.0, which was
+generated by GNU Autoconf 2.71.  Invocation command line was
+
+  $ $0$ac_configure_args_raw
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    printf "%s\n" "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Sanitize IFS.
+  IFS=" ""	$as_nl"
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    printf "%s\n" "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    printf "%s\n" "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      printf "%s\n" "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      printf "%s\n" "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	printf "%s\n" "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      printf "%s\n" "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      printf "%s\n" "$as_me: caught signal $ac_signal"
+    printf "%s\n" "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+printf "%s\n" "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h
+
+printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+if test -n "$CONFIG_SITE"; then
+  ac_site_files="$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+  ac_site_files="$prefix/share/config.site $prefix/etc/config.site"
+else
+  ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+fi
+
+for ac_site_file in $ac_site_files
+do
+  case $ac_site_file in #(
+  */*) :
+     ;; #(
+  *) :
+    ac_site_file=./$ac_site_file ;;
+esac
+  if test -f "$ac_site_file" && test -r "$ac_site_file"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Test code for whether the C compiler supports C89 (global declarations)
+ac_c_conftest_c89_globals='
+/* Does the compiler advertise C89 conformance?
+   Do not test the value of __STDC__, because some compilers set it to 0
+   while being otherwise adequately conformant. */
+#if !defined __STDC__
+# error "Compiler does not advertise C89 conformance"
+#endif
+
+#include <stddef.h>
+#include <stdarg.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7 src/conf.sh.  */
+struct buf { int x; };
+struct buf * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not \xHH hex character constants.
+   These do not provoke an error unfortunately, instead are silently treated
+   as an "x".  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously \x00 != x always comes out true, for an
+   array size at least.  It is necessary to write \x00 == 0 to get something
+   that is true only with -std.  */
+int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) '\''x'\''
+int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),
+               int, int);'
+
+# Test code for whether the C compiler supports C89 (body of main).
+ac_c_conftest_c89_main='
+ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);
+'
+
+# Test code for whether the C compiler supports C99 (global declarations)
+ac_c_conftest_c99_globals='
+// Does the compiler advertise C99 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
+# error "Compiler does not advertise C99 conformance"
+#endif
+
+#include <stdbool.h>
+extern int puts (const char *);
+extern int printf (const char *, ...);
+extern int dprintf (int, const char *, ...);
+extern void *malloc (size_t);
+
+// Check varargs macros.  These examples are taken from C99 6.10.3.5.
+// dprintf is used instead of fprintf to avoid needing to declare
+// FILE and stderr.
+#define debug(...) dprintf (2, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+  int x = 1234;
+  int y = 5678;
+  debug ("Flag");
+  debug ("X = %d\n", x);
+  showlist (The first, second, and third items.);
+  report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+  #error "your preprocessor is broken"
+#endif
+#if BIG_OK
+#else
+  #error "your preprocessor is broken"
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+  int datasize;
+  double data[];
+};
+
+struct named_init {
+  int number;
+  const wchar_t *name;
+  double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+  // See if C++-style comments work.
+  // Iterate through items via the restricted pointer.
+  // Also check for declarations in for loops.
+  for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
+    continue;
+  return 0;
+}
+
+// Check varargs and va_copy.
+static bool
+test_varargs (const char *format, ...)
+{
+  va_list args;
+  va_start (args, format);
+  va_list args_copy;
+  va_copy (args_copy, args);
+
+  const char *str = "";
+  int number = 0;
+  float fnumber = 0;
+
+  while (*format)
+    {
+      switch (*format++)
+	{
+	case '\''s'\'': // string
+	  str = va_arg (args_copy, const char *);
+	  break;
+	case '\''d'\'': // int
+	  number = va_arg (args_copy, int);
+	  break;
+	case '\''f'\'': // float
+	  fnumber = va_arg (args_copy, double);
+	  break;
+	default:
+	  break;
+	}
+    }
+  va_end (args_copy);
+  va_end (args);
+
+  return *str && number && fnumber;
+}
+'
+
+# Test code for whether the C compiler supports C99 (body of main).
+ac_c_conftest_c99_main='
+  // Check bool.
+  _Bool success = false;
+  success |= (argc != 0);
+
+  // Check restrict.
+  if (test_restrict ("String literal") == 0)
+    success = true;
+  char *restrict newvar = "Another string";
+
+  // Check varargs.
+  success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);
+  test_varargs_macros ();
+
+  // Check flexible array members.
+  struct incomplete_array *ia =
+    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+  ia->datasize = 10;
+  for (int i = 0; i < ia->datasize; ++i)
+    ia->data[i] = i * 1.234;
+
+  // Check named initializers.
+  struct named_init ni = {
+    .number = 34,
+    .name = L"Test wide string",
+    .average = 543.34343,
+  };
+
+  ni.number = 58;
+
+  int dynamic_array[ni.number];
+  dynamic_array[0] = argv[0][0];
+  dynamic_array[ni.number - 1] = 543;
+
+  // work around unused variable warnings
+  ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''
+	 || dynamic_array[ni.number - 1] != 543);
+'
+
+# Test code for whether the C compiler supports C11 (global declarations)
+ac_c_conftest_c11_globals='
+// Does the compiler advertise C11 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
+# error "Compiler does not advertise C11 conformance"
+#endif
+
+// Check _Alignas.
+char _Alignas (double) aligned_as_double;
+char _Alignas (0) no_special_alignment;
+extern char aligned_as_int;
+char _Alignas (0) _Alignas (int) aligned_as_int;
+
+// Check _Alignof.
+enum
+{
+  int_alignment = _Alignof (int),
+  int_array_alignment = _Alignof (int[100]),
+  char_alignment = _Alignof (char)
+};
+_Static_assert (0 < -_Alignof (int), "_Alignof is signed");
+
+// Check _Noreturn.
+int _Noreturn does_not_return (void) { for (;;) continue; }
+
+// Check _Static_assert.
+struct test_static_assert
+{
+  int x;
+  _Static_assert (sizeof (int) <= sizeof (long int),
+                  "_Static_assert does not work in struct");
+  long int y;
+};
+
+// Check UTF-8 literals.
+#define u8 syntax error!
+char const utf8_literal[] = u8"happens to be ASCII" "another string";
+
+// Check duplicate typedefs.
+typedef long *long_ptr;
+typedef long int *long_ptr;
+typedef long_ptr long_ptr;
+
+// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
+struct anonymous
+{
+  union {
+    struct { int i; int j; };
+    struct { int k; long int l; } w;
+  };
+  int m;
+} v1;
+'
+
+# Test code for whether the C compiler supports C11 (body of main).
+ac_c_conftest_c11_main='
+  _Static_assert ((offsetof (struct anonymous, i)
+		   == offsetof (struct anonymous, w.k)),
+		  "Anonymous union alignment botch");
+  v1.i = 2;
+  v1.w.k = 5;
+  ok |= v1.i != 5;
+'
+
+# Test code for whether the C compiler supports C11 (complete).
+ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+${ac_c_conftest_c11_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  ${ac_c_conftest_c11_main}
+  return ok;
+}
+"
+
+# Test code for whether the C compiler supports C99 (complete).
+ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  return ok;
+}
+"
+
+# Test code for whether the C compiler supports C89 (complete).
+ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  return ok;
+}
+"
+
+as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H"
+as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H"
+as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H"
+as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H"
+as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H"
+as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"
+as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
+as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
+as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
+as_fn_append ac_header_c_list " vfork.h vfork_h HAVE_VFORK_H"
+as_fn_append ac_func_c_list " fork HAVE_FORK"
+as_fn_append ac_func_c_list " vfork HAVE_VFORK"
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+printf "%s\n" "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+printf "%s\n" "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file'
+	    and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# Safety check: Ensure that we are in the correct source directory.
+
+
+ac_config_headers="$ac_config_headers include/HsProcessConfig.h"
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
+set dummy ${ac_tool_prefix}clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "clang", so it can be a program name with args.
+set dummy clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+
+
+test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion -version; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+printf %s "checking whether the C compiler works... " >&6; }
+ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else $as_nop
+  ac_file=''
+fi
+if test -z "$ac_file"
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+printf %s "checking for C compiler default output file name... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+printf "%s\n" "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+printf %s "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else $as_nop
+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+printf "%s\n" "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main (void)
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+printf %s "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+printf "%s\n" "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+printf %s "checking for suffix of object files... " >&6; }
+if test ${ac_cv_objext+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+printf "%s\n" "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
+printf %s "checking whether the compiler supports GNU C... " >&6; }
+if test ${ac_cv_c_compiler_gnu+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_compiler_gnu=yes
+else $as_nop
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+y}
+ac_save_CFLAGS=$CFLAGS
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+printf %s "checking whether $CC accepts -g... " >&6; }
+if test ${ac_cv_prog_cc_g+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_g=yes
+else $as_nop
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+else $as_nop
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
+if test $ac_test_CFLAGS; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+ac_prog_cc_stdc=no
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
+printf %s "checking for $CC option to enable C11 features... " >&6; }
+if test ${ac_cv_prog_cc_c11+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c11=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c11_program
+_ACEOF
+for ac_arg in '' -std=gnu11
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c11=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c11" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c11" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c11" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
+printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
+     CC="$CC $ac_cv_prog_cc_c11"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
+  ac_prog_cc_stdc=c11
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
+printf %s "checking for $CC option to enable C99 features... " >&6; }
+if test ${ac_cv_prog_cc_c99+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c99_program
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c99" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c99" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
+     CC="$CC $ac_cv_prog_cc_c99"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
+  ac_prog_cc_stdc=c99
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
+printf %s "checking for $CC option to enable C89 features... " >&6; }
+if test ${ac_cv_prog_cc_c89+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c89_program
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c89" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c89" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
+     CC="$CC $ac_cv_prog_cc_c89"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+  ac_prog_cc_stdc=c89
+fi
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_header= ac_cache=
+for ac_item in $ac_header_c_list
+do
+  if test $ac_cache; then
+    ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
+    if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
+      printf "%s\n" "#define $ac_item 1" >> confdefs.h
+    fi
+    ac_header= ac_cache=
+  elif test $ac_header; then
+    ac_cache=$ac_item
+  else
+    ac_header=$ac_item
+  fi
+done
+
+
+
+
+
+
+
+
+if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
+then :
+
+printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+  ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default
+"
+if test "x$ac_cv_type_pid_t" = xyes
+then :
+
+else $as_nop
+                                          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+          #if defined _WIN64 && !defined __CYGWIN__
+          LLP64
+          #endif
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_pid_type='int'
+else $as_nop
+  ac_pid_type='__int64'
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+
+printf "%s\n" "#define pid_t $ac_pid_type" >>confdefs.h
+
+
+fi
+
+
+
+ac_func=
+for ac_item in $ac_func_c_list
+do
+  if test $ac_func; then
+    ac_fn_c_check_func "$LINENO" $ac_func ac_cv_func_$ac_func
+    if eval test \"x\$ac_cv_func_$ac_func\" = xyes; then
+      echo "#define $ac_item 1" >> confdefs.h
+    fi
+    ac_func=
+  else
+    ac_func=$ac_item
+  fi
+done
+
+
+
+if test "x$ac_cv_func_fork" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
+printf %s "checking for working fork... " >&6; }
+if test ${ac_cv_func_fork_works+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test "$cross_compiling" = yes
+then :
+  ac_cv_func_fork_works=cross
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main (void)
+{
+
+	  /* By Ruediger Kuhlmann. */
+	  return fork () < 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"
+then :
+  ac_cv_func_fork_works=yes
+else $as_nop
+  ac_cv_func_fork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
+printf "%s\n" "$ac_cv_func_fork_works" >&6; }
+
+else
+  ac_cv_func_fork_works=$ac_cv_func_fork
+fi
+if test "x$ac_cv_func_fork_works" = xcross; then
+  case $host in
+    *-*-amigaos* | *-*-msdosdjgpp*)
+      # Override, as these systems have only a dummy fork() stub
+      ac_cv_func_fork_works=no
+      ;;
+    *)
+      ac_cv_func_fork_works=yes
+      ;;
+  esac
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
+printf "%s\n" "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
+fi
+ac_cv_func_vfork_works=$ac_cv_func_vfork
+if test "x$ac_cv_func_vfork" = xyes; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
+printf %s "checking for working vfork... " >&6; }
+if test ${ac_cv_func_vfork_works+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test "$cross_compiling" = yes
+then :
+  ac_cv_func_vfork_works=cross
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Thanks to Paul Eggert for this test.  */
+$ac_includes_default
+#include <signal.h>
+#include <sys/wait.h>
+#ifdef HAVE_VFORK_H
+# include <vfork.h>
+#endif
+
+static void
+do_nothing (int sig)
+{
+  (void) sig;
+}
+
+/* On some sparc systems, changes by the child to local and incoming
+   argument registers are propagated back to the parent.  The compiler
+   is told about this with #include <vfork.h>, but some compilers
+   (e.g. gcc -O) don't grok <vfork.h>.  Test for this by using a
+   static variable whose address is put into a register that is
+   clobbered by the vfork.  */
+static void
+sparc_address_test (int arg)
+{
+  static pid_t child;
+  if (!child) {
+    child = vfork ();
+    if (child < 0) {
+      perror ("vfork");
+      _exit(2);
+    }
+    if (!child) {
+      arg = getpid();
+      write(-1, "", 0);
+      _exit (arg);
+    }
+  }
+}
+
+int
+main (void)
+{
+  pid_t parent = getpid ();
+  pid_t child;
+
+  sparc_address_test (0);
+
+  /* On Solaris 2.4, changes by the child to the signal handler
+     also munge signal handlers in the parent.  To detect this,
+     start by putting the parent's handler in a known state.  */
+  signal (SIGTERM, SIG_DFL);
+
+  child = vfork ();
+
+  if (child == 0) {
+    /* Here is another test for sparc vfork register problems.  This
+       test uses lots of local variables, at least as many local
+       variables as main has allocated so far including compiler
+       temporaries.  4 locals are enough for gcc 1.40.3 on a Solaris
+       4.1.3 sparc, but we use 8 to be safe.  A buggy compiler should
+       reuse the register of parent for one of the local variables,
+       since it will think that parent can't possibly be used any more
+       in this routine.  Assigning to the local variable will thus
+       munge parent in the parent process.  */
+    pid_t
+      p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+      p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+    /* Convince the compiler that p..p7 are live; otherwise, it might
+       use the same hardware register for all 8 local variables.  */
+    if (p != p1 || p != p2 || p != p3 || p != p4
+	|| p != p5 || p != p6 || p != p7)
+      _exit(1);
+
+    /* Alter the child's signal handler.  */
+    if (signal (SIGTERM, do_nothing) != SIG_DFL)
+      _exit(1);
+
+    /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
+       from child file descriptors.  If the child closes a descriptor
+       before it execs or exits, this munges the parent's descriptor
+       as well.  Test for this by closing stdout in the child.  */
+    _exit(close(fileno(stdout)) != 0);
+  } else {
+    int status;
+    struct stat st;
+
+    while (wait(&status) != child)
+      ;
+    return (
+	 /* Was there some problem with vforking?  */
+	 child < 0
+
+	 /* Did the child munge the parent's signal handler?  */
+	 || signal (SIGTERM, SIG_DFL) != SIG_DFL
+
+	 /* Did the child fail?  (This shouldn't happen.)  */
+	 || status
+
+	 /* Did the vfork/compiler bug occur?  */
+	 || parent != getpid()
+
+	 /* Did the file descriptor bug occur?  */
+	 || fstat(fileno(stdout), &st) != 0
+	 );
+  }
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"
+then :
+  ac_cv_func_vfork_works=yes
+else $as_nop
+  ac_cv_func_vfork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
+printf "%s\n" "$ac_cv_func_vfork_works" >&6; }
+
+fi;
+if test "x$ac_cv_func_fork_works" = xcross; then
+  ac_cv_func_vfork_works=$ac_cv_func_vfork
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
+printf "%s\n" "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
+fi
+
+if test "x$ac_cv_func_vfork_works" = xyes; then
+
+printf "%s\n" "#define HAVE_WORKING_VFORK 1" >>confdefs.h
+
+else
+
+printf "%s\n" "#define vfork fork" >>confdefs.h
+
+fi
+if test "x$ac_cv_func_fork_works" = xyes; then
+
+printf "%s\n" "#define HAVE_WORKING_FORK 1" >>confdefs.h
+
+fi
+
+
+# check for specific header (.h) files that we are interested in
+ac_fn_c_check_header_compile "$LINENO" "signal.h" "ac_cv_header_signal_h" "$ac_includes_default"
+if test "x$ac_cv_header_signal_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SIGNAL_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_wait_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default"
+if test "x$ac_cv_header_fcntl_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_FCNTL_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_func "$LINENO" "setitimer" "ac_cv_func_setitimer"
+if test "x$ac_cv_func_setitimer" = xyes
+then :
+  printf "%s\n" "#define HAVE_SETITIMER 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "sysconf" "ac_cv_func_sysconf"
+if test "x$ac_cv_func_sysconf" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYSCONF 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_func "$LINENO" "execvpe" "ac_cv_func_execvpe"
+if test "x$ac_cv_func_execvpe" = xyes
+then :
+  printf "%s\n" "#define HAVE_EXECVPE 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+  printf "%s\n" "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+
+# posix_spawn checks
+ac_fn_c_check_header_compile "$LINENO" "spawn.h" "ac_cv_header_spawn_h" "$ac_includes_default"
+if test "x$ac_cv_header_spawn_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SPAWN_H 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_func "$LINENO" "posix_spawnp" "ac_cv_func_posix_spawnp"
+if test "x$ac_cv_func_posix_spawnp" = xyes
+then :
+  printf "%s\n" "#define HAVE_POSIX_SPAWNP 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "posix_spawn_file_actions_addchdir_np" "ac_cv_func_posix_spawn_file_actions_addchdir_np"
+if test "x$ac_cv_func_posix_spawn_file_actions_addchdir_np" = xyes
+then :
+  printf "%s\n" "#define HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "posix_spawn_file_actions_addchdir" "ac_cv_func_posix_spawn_file_actions_addchdir"
+if test "x$ac_cv_func_posix_spawn_file_actions_addchdir" = xyes
+then :
+  printf "%s\n" "#define HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR 1" >>confdefs.h
+
+fi
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5
+printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; }
+if test ${ac_cv_c_undeclared_builtin_options+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_save_CFLAGS=$CFLAGS
+   ac_cv_c_undeclared_builtin_options='cannot detect'
+   for ac_arg in '' -fno-builtin; do
+     CFLAGS="$ac_save_CFLAGS $ac_arg"
+     # This test program should *not* compile successfully.
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+(void) strchr;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+else $as_nop
+  # This test program should compile successfully.
+        # No library function is consistently available on
+        # freestanding implementations, so test against a dummy
+        # declaration.  Include always-available headers on the
+        # off chance that they somehow elicit warnings.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <float.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stddef.h>
+extern void ac_decl (int, char *);
+
+int
+main (void)
+{
+(void) ac_decl (0, (char *) 0);
+  (void) ac_decl;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  if test x"$ac_arg" = x
+then :
+  ac_cv_c_undeclared_builtin_options='none needed'
+else $as_nop
+  ac_cv_c_undeclared_builtin_options=$ac_arg
+fi
+          break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+    done
+    CFLAGS=$ac_save_CFLAGS
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5
+printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; }
+  case $ac_cv_c_undeclared_builtin_options in #(
+  'cannot detect') :
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot make $CC report undeclared builtins
+See \`config.log' for more details" "$LINENO" 5; } ;; #(
+  'none needed') :
+    ac_c_undeclared_builtin_options='' ;; #(
+  *) :
+    ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;;
+esac
+
+ac_fn_check_decl "$LINENO" "POSIX_SPAWN_SETSID" "ac_cv_have_decl_POSIX_SPAWN_SETSID" "
+  #define _GNU_SOURCE
+  #include <spawn.h>
+
+" "$ac_c_undeclared_builtin_options" "CFLAGS"
+if test "x$ac_cv_have_decl_POSIX_SPAWN_SETSID" = xyes
+then :
+  ac_have_decl=1
+else $as_nop
+  ac_have_decl=0
+fi
+printf "%s\n" "#define HAVE_DECL_POSIX_SPAWN_SETSID $ac_have_decl" >>confdefs.h
+ac_fn_check_decl "$LINENO" "POSIX_SPAWN_SETSID_NP" "ac_cv_have_decl_POSIX_SPAWN_SETSID_NP" "
+  #define _GNU_SOURCE
+  #include <spawn.h>
+
+" "$ac_c_undeclared_builtin_options" "CFLAGS"
+if test "x$ac_cv_have_decl_POSIX_SPAWN_SETSID_NP" = xyes
+then :
+  ac_have_decl=1
+else $as_nop
+  ac_have_decl=0
+fi
+printf "%s\n" "#define HAVE_DECL_POSIX_SPAWN_SETSID_NP $ac_have_decl" >>confdefs.h
+
+ac_fn_check_decl "$LINENO" "POSIX_SPAWN_SETPGROUP" "ac_cv_have_decl_POSIX_SPAWN_SETPGROUP" "
+  #define _GNU_SOURCE
+  #include <spawn.h>
+
+" "$ac_c_undeclared_builtin_options" "CFLAGS"
+if test "x$ac_cv_have_decl_POSIX_SPAWN_SETPGROUP" = xyes
+then :
+  ac_have_decl=1
+else $as_nop
+  ac_have_decl=0
+fi
+printf "%s\n" "#define HAVE_DECL_POSIX_SPAWN_SETPGROUP $ac_have_decl" >>confdefs.h
+
+
+if test "$ac_cv_func_posix_spawnp" = "yes"; then
+
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether posix_spawn reports errors sensibly" >&5
+printf %s "checking whether posix_spawn reports errors sensibly... " >&6; }
+    if test "$cross_compiling" = yes
+then :
+  printf "%s\n" "#define USE_POSIX_SPAWN /**/" >>confdefs.h
+
+          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cross-compiling - assuming yes" >&5
+printf "%s\n" "cross-compiling - assuming yes" >&6; }
+
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+             #include <stddef.h>
+             #include <stdbool.h>
+             #include <errno.h>
+             #include <spawn.h>
+
+int
+main (void)
+{
+
+                 pid_t pid;
+                 char *prog = "__nonexistent_program__";
+                 char *args[] = {prog, NULL};
+                 char *env[] = {NULL};
+
+                 // This should fail with ENOENT
+                 int ret = posix_spawnp(&pid, prog, NULL, NULL, args, env);
+                 bool okay = ret == ENOENT;
+                 return !okay;
+
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"
+then :
+
+printf "%s\n" "#define USE_POSIX_SPAWN /**/" >>confdefs.h
+
+          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, falling back to fork/exec" >&5
+printf "%s\n" "no, falling back to fork/exec" >&6; }
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+
+
+for fp_const_name in SIG_DFL SIG_IGN
+do
+as_fp_Cache=`printf "%s\n" "fp_cv_const_$fp_const_name" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking value of $fp_const_name" >&5
+printf %s "checking value of $fp_const_name... " >&6; }
+if eval test \${$as_fp_Cache+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if ac_fn_c_compute_int "$LINENO" "$fp_const_name" "fp_check_const_result"        "$ac_includes_default"
+then :
+
+else $as_nop
+  fp_check_const_result='-1'
+fi
+
+eval "$as_fp_Cache=\$fp_check_const_result"
+fi
+eval ac_res=\$$as_fp_Cache
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+cat >>confdefs.h <<_ACEOF
+#define `printf "%s\n" "CONST_$fp_const_name" | $as_tr_cpp` `eval 'as_val=${'$as_fp_Cache'};printf "%s\n" "$as_val"'`
+_ACEOF
+
+done
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else $as_nop
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
+as_nl='
+'
+export as_nl
+IFS=" ""	$as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
+
+# The user is always right.
+if ${PATH_SEPARATOR+false} :; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  printf "%s\n" "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else $as_nop
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else $as_nop
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by Haskell process package $as_me 1.0, which was
+generated by GNU Autoconf 2.71.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration headers:
+$config_headers
+
+Report bugs to <libraries@haskell.org>."
+
+_ACEOF
+ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
+ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config='$ac_cs_config_escaped'
+ac_cs_version="\\
+Haskell process package config.status 1.0
+configured by $0, generated by GNU Autoconf 2.71,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2021 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    printf "%s\n" "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    printf "%s\n" "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    printf "%s\n" "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  printf "%s\n" "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "include/HsProcessConfig.h") CONFIG_HEADERS="$CONFIG_HEADERS include/HsProcessConfig.h" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "    :H $CONFIG_HEADERS    "
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+printf "%s\n" "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`printf "%s\n" "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      printf "%s\n" "/* $configure_input  */" >&1 \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+printf "%s\n" "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    printf "%s\n" "/* $configure_input  */" >&1 \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+ ;;
+
+
+  esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
 
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -1,22 +1,75 @@
-AC_INIT([Haskell process package], [1.0], [libraries@haskell.org], [process])
+AC_INIT([Haskell process package],[1.0],[libraries@haskell.org],[process])
 
 # Safety check: Ensure that we are in the correct source directory.
 AC_CONFIG_SRCDIR([include/runProcess.h])
 
 AC_CONFIG_HEADERS([include/HsProcessConfig.h])
 
-AC_ARG_WITH([cc],
-            [C compiler],
-            [CC=$withval])
-AC_PROG_CC()
+AC_PROG_CC
 
-dnl ** Working vfork?
+dnl ** Working fork?
 AC_FUNC_FORK
 
 # check for specific header (.h) files that we are interested in
 AC_CHECK_HEADERS([signal.h sys/wait.h fcntl.h])
 
 AC_CHECK_FUNCS([setitimer sysconf])
+AC_CHECK_FUNCS([execvpe])
+AC_CHECK_FUNCS([pipe2],[],[],[
+  #define _GNU_SOURCE
+  #include <unistd.h>
+  #include <fcntl.h>
+])
+
+# posix_spawn checks
+AC_CHECK_HEADERS([spawn.h])
+AC_CHECK_FUNCS([posix_spawnp posix_spawn_file_actions_addchdir_np posix_spawn_file_actions_addchdir],[],[],[
+  #define _GNU_SOURCE
+  #include <spawn.h>
+])
+AC_CHECK_DECLS([POSIX_SPAWN_SETSID, POSIX_SPAWN_SETSID_NP],[],[],[
+  #define _GNU_SOURCE
+  #include <spawn.h>
+])
+AC_CHECK_DECLS([POSIX_SPAWN_SETPGROUP],[],[],[
+  #define _GNU_SOURCE
+  #include <spawn.h>
+])
+
+if test "$ac_cv_func_posix_spawnp" = "yes"; then
+    dnl On OpenBSD posix_spawnp doesn't report ENOENT when
+    dnl the user attempts to spawn a process with a non-existent
+    dnl executable. Don't attempt to use such posix_spawn
+    dnl implementations to ensure errors are reported correctly.
+    dnl See #224.
+
+    AC_MSG_CHECKING(whether posix_spawn reports errors sensibly)
+    AC_RUN_IFELSE(
+        [AC_LANG_PROGRAM([
+             #include <stddef.h>
+             #include <stdbool.h>
+             #include <errno.h>
+             #include <spawn.h>
+           ], [[
+                 pid_t pid;
+                 char *prog = "__nonexistent_program__";
+                 char *args[] = {prog, NULL};
+                 char *env[] = {NULL};
+
+                 // This should fail with ENOENT
+                 int ret = posix_spawnp(&pid, prog, NULL, NULL, args, env);
+                 bool okay = ret == ENOENT;
+                 return !okay;
+           ]]
+         )],
+         [AC_DEFINE([USE_POSIX_SPAWN], [], [posix_spawn should be used])
+          AC_MSG_RESULT(yes)],
+         [AC_MSG_RESULT([no, falling back to fork/exec])],
+         [AC_DEFINE([USE_POSIX_SPAWN], [], [])
+          AC_MSG_RESULT(cross-compiling - assuming yes)]
+    )
+fi
+
 
 FP_CHECK_CONSTS([SIG_DFL SIG_IGN])
 
diff --git a/exes/echo.bat b/exes/echo.bat
new file mode 100644
--- /dev/null
+++ b/exes/echo.bat
@@ -0,0 +1,1 @@
+echo parent
diff --git a/exes/subdir/echo.bat b/exes/subdir/echo.bat
new file mode 100644
--- /dev/null
+++ b/exes/subdir/echo.bat
@@ -0,0 +1,1 @@
+echo child
diff --git a/include/HsProcessConfig.h.in b/include/HsProcessConfig.h.in
--- a/include/HsProcessConfig.h.in
+++ b/include/HsProcessConfig.h.in
@@ -6,6 +6,21 @@
 /* The value of SIG_IGN. */
 #undef CONST_SIG_IGN
 
+/* Define to 1 if you have the declaration of `POSIX_SPAWN_SETPGROUP', and to
+   0 if you don't. */
+#undef HAVE_DECL_POSIX_SPAWN_SETPGROUP
+
+/* Define to 1 if you have the declaration of `POSIX_SPAWN_SETSID', and to 0
+   if you don't. */
+#undef HAVE_DECL_POSIX_SPAWN_SETSID
+
+/* Define to 1 if you have the declaration of `POSIX_SPAWN_SETSID_NP', and to
+   0 if you don't. */
+#undef HAVE_DECL_POSIX_SPAWN_SETSID_NP
+
+/* Define to 1 if you have the `execvpe' function. */
+#undef HAVE_EXECVPE
+
 /* Define to 1 if you have the <fcntl.h> header file. */
 #undef HAVE_FCNTL_H
 
@@ -15,18 +30,35 @@
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
+/* Define to 1 if you have the `pipe2' function. */
+#undef HAVE_PIPE2
 
+/* Define to 1 if you have the `posix_spawnp' function. */
+#undef HAVE_POSIX_SPAWNP
+
+/* Define to 1 if you have the `posix_spawn_file_actions_addchdir' function.
+   */
+#undef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR
+
+/* Define to 1 if you have the `posix_spawn_file_actions_addchdir_np'
+   function. */
+#undef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP
+
 /* Define to 1 if you have the `setitimer' function. */
 #undef HAVE_SETITIMER
 
 /* Define to 1 if you have the <signal.h> header file. */
 #undef HAVE_SIGNAL_H
 
+/* Define to 1 if you have the <spawn.h> header file. */
+#undef HAVE_SPAWN_H
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
@@ -81,10 +113,15 @@
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
-/* Define to 1 if you have the ANSI C header files. */
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
 #undef STDC_HEADERS
 
-/* Define to `int' if <sys/types.h> does not define. */
+/* posix_spawn should be used */
+#undef USE_POSIX_SPAWN
+
+/* Define as a signed integer type capable of holding a process identifier. */
 #undef pid_t
 
 /* Define as `fork' if `vfork' does not work. */
diff --git a/include/processFlags.h b/include/processFlags.h
--- a/include/processFlags.h
+++ b/include/processFlags.h
@@ -9,3 +9,4 @@
 #define RUN_PROCESS_DETACHED     0x4
 #define RUN_PROCESS_NEW_SESSION  0x8
 #define RUN_PROCESS_NEW_CONSOLE  0x10
+#define RESET_INT_QUIT_HANDLERS  0x20
diff --git a/include/runProcess.h b/include/runProcess.h
--- a/include/runProcess.h
+++ b/include/runProcess.h
@@ -4,6 +4,8 @@
    Interface for code in runProcess.c (providing support for System.Process)
    ------------------------------------------------------------------------- */
 
+#pragma once
+
 #include "HsProcessConfig.h"
 // Otherwise these clash with similar definitions from other packages:
 #undef PACKAGE_BUGREPORT
@@ -16,33 +18,11 @@
 #define UNICODE
 #include <windows.h>
 #include <stdlib.h>
-#endif
-
-#include <unistd.h>
-#include <sys/types.h>
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_VFORK_H
-#include <vfork.h>
-#endif
-
-#if defined(HAVE_WORKING_VFORK)
-#define myfork vfork
-#elif defined(HAVE_WORKING_FORK)
-#define myfork fork
-// We don't need a fork command on Windows
-#elif !(defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32))
-#error Cannot find a working fork command
-#endif
-
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
+#include <stdbool.h>
 #endif
 
 #if !(defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32))
+#include <sys/types.h>
 typedef pid_t ProcHandle;
 #else
 // Should really be intptr_t, but we don't have that type on the Haskell side
@@ -51,18 +31,26 @@
 
 #include "processFlags.h"
 
-#if !(defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32))
+#include <ghcplatform.h>
 
-extern ProcHandle runInteractiveProcess( char *const args[], 
-                                         char *workingDirectory, 
-                                         char **environment, 
+#if defined(wasm32_HOST_ARCH)
+
+#elif !(defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32))
+
+#include <pwd.h>
+#include <grp.h>
+
+extern ProcHandle runInteractiveProcess( char *const args[],
+                                         char *workingDirectory,
+                                         char **environment,
                                          int fdStdIn,
                                          int fdStdOut,
                                          int fdStdErr,
-                                         int *pfdStdInput, 
-                                         int *pfdStdOutput, 
+                                         int *pfdStdInput,
+                                         int *pfdStdOutput,
                                          int *pfdStdError,
-                                         int reset_int_quit_handlers,
+                                         gid_t *childGroup,
+                                         uid_t *childUser,
                                          int flags,
                                          char **failed_doing);
 
@@ -77,7 +65,25 @@
                                          int *pfdStdInput,
                                          int *pfdStdOutput,
                                          int *pfdStdError,
-                                         int flags);
+                                         int flags,
+                                         bool useJobObject,
+                                         HANDLE *hJob );
+
+extern ProcHandle runInteractiveProcessHANDLE ( wchar_t *cmd,
+                                                wchar_t *workingDirectory,
+                                                wchar_t *environment,
+                                                HANDLE _stdin,
+                                                HANDLE _stdout,
+                                                HANDLE _stderr,
+                                                HANDLE *pStdInput,
+                                                HANDLE *pStdOutput,
+                                                HANDLE *pStdError,
+                                                int flags,
+                                                bool useJobObject,
+                                                HANDLE *hJob);
+
+extern int terminateJob( ProcHandle handle );
+extern int waitForJobCompletion( HANDLE hJob );
 
 #endif
 
diff --git a/jsbits/process.js b/jsbits/process.js
new file mode 100644
--- /dev/null
+++ b/jsbits/process.js
@@ -0,0 +1,581 @@
+//#OPTIONS: CPP
+
+// #define JS_TRACE_PROCESS 1
+
+#ifdef JS_TRACE_PROCESS
+function h$logProcess() { h$log.apply(h$log,arguments); }
+#define TRACE_PROCESS(args...) h$logProcess(args)
+#else
+#define TRACE_PROCESS(args...)
+#endif
+
+/*
+   Convert from a string signal name to a signal number.
+
+   To ensure consistent signal numbers between platforms we use signal
+   numbers from the emscripten SDK whenever we use a numeric signal code.
+
+   These might differ from the actual numbers of the operating system
+   on which the nodejs process is running.
+
+   list from emscripten /system/lib/libc/musl/arch/emscripten/bits/signal.h
+
+   Note: we should possibly move this into the base or rts package in the future
+  */
+var h$process_signals = {
+    'SIGHUP': 1,
+    'SIGINT': 2,
+    'SIGQUIT': 3,
+    'SIGILL': 4,
+    'SIGTRAP': 5,
+    'SIGABRT': 6,
+    'SIGIOT': 6,
+    'SIGBUS': 7,
+    'SIGFPE': 8,
+    'SIGKILL': 9,
+    'SIGUSR1': 10,
+    'SIGSEGV': 11,
+    'SIGUSR2': 12,
+    'SIGPIPE': 13,
+    'SIGALRM': 14,
+    'SIGTERM': 15,
+    'SIGSTKFLT': 16,
+    'SIGCHLD': 17,
+    'SIGCONT': 18,
+    'SIGSTOP': 19,
+    'SIGTSTP': 20,
+    'SIGTTIN': 21,
+    'SIGTTOU': 22,
+    'SIGURG': 23,
+    'SIGXCPU': 24,
+    'SIGXFSZ': 25,
+    'SIGVTALRM': 26,
+    'SIGPROF': 27,
+    'SIGWINCH': 28,
+    'SIGIO': 29,
+    'SIGPOLL': 29,
+    'SIGPWR': 30,
+    'SIGSYS': 31,
+    'SIGUNUSED': 31
+};
+
+/*
+   Create a one-directional pipe for communication with the child process
+
+     - pipe: a Readable or Writable stream from spawning the child process
+     - write: boolean - true if the pipe is for writing, false for reading
+ */
+function h$process_pipeFd(pipe, write) {
+    var fdN = h$base_fdN--, fd = {};
+    h$base_fds[fdN] = fd;
+    TRACE_PROCESS("pipe", fdN, "opened, writable:", write);
+
+    if(pipe && pipe._handle && typeof pipe._handle.fd === 'number') fd.fd = pipe._handle.fd;
+    TRACE_PROCESS("pipe real fd", fd.fd);
+
+    if(write) {
+        fd.err   = null;
+        fd.waiting = new h$Queue();
+        fd.close = function(fd, fdo, c) { delete h$base_fds[fd]; pipe.end(); c(0); };
+        fd.refs = 1;
+        pipe.on('error', function(err) {
+            TRACE_PROCESS("pipe received error", fd, err);
+            fd.err = err;
+        });
+        fd.write = function(fd, fdo, buf, buf_offset, n, c)  {
+            TRACE_PROCESS("pipe ", fd, " write:", n);
+            if(fdo.err) {
+                TRACE_PROCESS("pipe error", fdo.err);
+                h$setErrno(fdo.err);
+                c(-1);
+                return;
+            }
+            var nbuf = buf.u8.slice(buf_offset, buf_offset+n);
+            var r = pipe.write(nbuf, function() {
+                TRACE_PROCESS("pipe", fd, "flushed");
+                c(n);
+            });
+            TRACE_PROCESS("pipe write", fd, "result", r);
+        }
+    } else {
+        fd.close      = function(fd, fdo, c) { delete h$base_fds[fd]; c(0); }
+        fd.refs       = 1;
+        fd.waiting    = new h$Queue();
+        fd.chunk      = { buf: null, pos: 0, processing: false };
+        fd.eof        = false;
+        fd.err        = null;
+        fd.reading    = false;
+
+        pipe.on('end', function() {
+            TRACE_PROCESS("pipe", fdN, fd.fd, "eof");
+            fd.eof = true;
+            h$process_process_pipe(fd, pipe);
+        });
+        pipe.on('error', function(err) {
+            TRACE_PROCESS("pipe received error", fdN, fd.fd);
+            fd.err = err;
+            h$process_process_pipe(fd, pipe);
+        });
+        fd.read = function(fd, fdo, buf, buf_offset, n, c) {
+            if(!fdo.reading) {
+                /*
+                   Reading is a blocking operation (asynchronous) from the Haskell
+                   side. On the JavaScript side we rely on the 'readable' event to
+                   know when there is available data. Every time data comes in we
+                   process the queue of waiting read requests.
+
+                   We don't attach the 'readable' event handler until we actually
+                   read from the pipe, since the readable handler causes the node.js
+                   process to start buffering data from the file descriptor.
+
+                   If we don't read from the file descriptor it is unaffected by
+                   node.js buffering and we can for example pass it to another child
+                   process to allow direct communication between multiple child
+                   processes.
+                 */
+                pipe.on('readable', function() {
+                    TRACE_PROCESS("pipe", fdN, fd.fd, "readable");
+                    h$process_process_pipe(fdo, pipe);
+                });
+                fdo.reading = true;
+                h$process_process_pipe(fdo, pipe);
+            }
+            TRACE_PROCESS("pipe", fdN, fd.fd, "read", n, fdo.chunk.buf);
+            fdo.waiting.enqueue({buf: buf, off: buf_offset, n: n, c: c});
+            h$process_process_pipe(fdo, pipe);
+        }
+    }
+    TRACE_PROCESS("created pipe, fd:", fdN);
+    return fdN;
+}
+
+/*
+    Process the queue of waiting read/write requests for a pipe
+ */
+function h$process_process_pipe(fd, pipe) {
+    var c = fd.chunk;
+    var q = fd.waiting;
+    TRACE_PROCESS("processing pipe", fd);
+    if(!q || !q.length() || c.processing) return;
+    c.processing = true;
+    while(fd.err && q.length()) {
+        h$setErrno(fd.err);
+        q.dequeue().c(-1);
+    }
+    if(!c.buf) {
+        c.pos = 0;
+        c.buf = pipe.read();
+    }
+    while(c.buf && q.length()) {
+        var x = q.dequeue();
+        var n = Math.min(c.buf.length - c.pos, x.n);
+        for(var i=0;i<n;i++) {
+            x.buf.u8[i+x.off] = c.buf[c.pos+i];
+        }
+        c.pos += n;
+        x.c(n);
+        // XXX this does reorder the requests if data comes in small chunks
+        if(c.pos >= c.buf.length) c.buf = null;
+        if(!c.buf && q.length()) {
+            c.pos = 0;
+            c.buf = pipe.read();
+        }
+    }
+    while(fd.eof && q.length()) q.dequeue().c(0);
+    TRACE_PROCESS("done processing pipe, remaining queue", q.length());
+    c.processing = false;
+}
+
+/*
+    Start an interactive child process using the node.js child_prcess.spawn
+    functionality.
+
+    Even though this is mostly a non-blocking operation (we don't wait until
+    the child process has finished), this is an asynchronous function
+    (with a continuation) because we want to wait until the child process has
+    spawned before we resume the Haskell thread.
+
+    This allows us to raise exceptions if the process could not be started, for
+    example becaus of permission errors or a non-existent executable.
+
+    Calls the continuation with a process object, or null when spawning the
+    process has failed, after setting h$errno to the appropriate value.
+ */
+function h$process_runInteractiveProcess(
+      cmd           // string  - command to run
+    , args          // array of strings - arguments
+    , workingDir    // string  - working directory, null: unchanged
+    , env           // array of strings - environment [ key1, val1, key2, val2, ...]
+                    //                         null: inherit
+    , stdin_fd      // number   - stdin fd, -1: createpipe, -2: ignore
+    , stdout_fd     // number   - stdout fd, -1: createpipe, -2: ignore
+    , stderr_fd     // number   - stderr fd, -1: createpipe, -2: ignore
+    , _closeFds     // boolean  - close file descriptors in child (ignored)
+    , createGroup   // boolean  - create a new process group
+    , delegateCtlC  // boolean  - delegate control-C handling
+    , newSession    // boolean  - use posix setsid to start the process in a new session
+    , childGID      // number   - child group id, -1 for unchanged
+    , childUID      // number   - child user id, -1 for unchanged
+    , c             // function - continuation, called when the process has spawned
+    ) {
+    TRACE_PROCESS("runInteractiveProcess");
+    TRACE_PROCESS("cmd: ", cmd, " args: ", args);
+    TRACE_PROCESS("workingDir: ", workingDir, " env: ", env);
+    TRACE_PROCESS("stdin", stdin_fd, "stdout", stdout_fd, "stderr", stderr_fd);
+
+    if(h$isNode()) {
+        try {
+            var stdin_p, stdout_p, stderr_p;
+
+            function getStream(pos, spec) {
+                // CreatePipe
+                if(spec === -1) return 'pipe';
+
+                // NoStream
+                if(spec === -2) return 'ignore';
+
+                // standard streams
+                if(spec === 0) return spec == pos ? 'inherit' : process.stdin;
+                if(spec === 1) return spec == pos ? 'inherit' : process.stdout;
+                if(spec === 2) return spec == pos ? 'inherit' : process.stderr;
+
+                // registered fd
+                var stream = h$base_fds[spec];
+                if(typeof stream.fd === 'number') return stream.fd;
+
+                // raw fd
+                if(typeof spec === 'number' && spec > 0) return spec;
+
+                // unsupported stream type
+                // the exception is caught and converted to an errno status code below
+                throw new Error('EBADF');
+            }
+
+            stdin_p = getStream(0, stdin_fd);
+            stdout_p = getStream(1, stdout_fd);
+            stderr_p = getStream(2, stderr_fd);
+
+            var options = { detached: newSession || createGroup
+                          , stdio: [stdin_p, stdout_p, stderr_p]
+                          };
+            if(workingDir !== null) options.cwd = workingDir;
+            if(env !== null) {
+                var envObj = {};
+                for(var i=0;i<env.length;i+=2) envObj[env[i]] = env[i+1];
+                TRACE_PROCESS("environment: " + h$collectProps(envObj));
+                options.env = envObj;
+            }
+            if(childGID !== -1) options.gid = childGID;
+            if(childUID !== -1) options.uid = childUID;
+
+            var procObj;
+            var child;
+
+            // node.js on Windows x86 sometimes throw an EBADF exception when
+            // process.stdin is invalid, retry with ignored stdin when
+            // this happens.
+            TRACE_PROCESS("spawning process", cmd, args, options);
+
+            try {
+                child = h$child.spawn(cmd, args, options);
+            } catch(e) {
+                TRACE_PROCESS("spawning exception", e);
+
+                if(e.toString().indexOf('EBADF') !== -1 && options.stdio[0] === process.stdin) {
+                    options.stdio[0] = 'ignore';
+                    child = h$child.spawn(cmd, args, options);
+                } else {
+                    throw e;
+                }
+            }
+            TRACE_PROCESS("spawn done, setting handlers");
+
+            // keep track of whether the process has spawned, since we can get
+            // multiple events for this and we only want to call the continuation
+            // once.
+            var spawned = false;
+
+            child.on('exit', function(code, sig) {
+                TRACE_PROCESS("process finished", code, sig);
+                // if the spawn event hasn't fired we still have to call
+                // the continuation for that
+                if(!spawned) {
+                    spawned = true;
+                    c(procObj);
+                } else {
+                    if(delegateCtlC) {
+                        h$process_stopDelegateControlC();
+                    }
+                }
+                if(code === null) {
+                    // process was killed by a signal
+                    var signo = h$process_signals[sig] || 31;
+                    // The Haskell side expects a negative status if killed
+                    // by a signal
+                    code = -signo;
+                }
+                procObj.exit = code;
+
+                // notify all threads that are waiting for the exit code
+                for(var i=0;i<procObj.waiters.length;i++) {
+                    procObj.waiters[i](code);
+                }
+            });
+
+            child.on('spawn', function() {
+                TRACE_PROCESS("process spawned");
+                if(!spawned) {
+                    if(delegateCtlC) {
+                        h$process_startDelegateControlC();
+                    }
+                    spawned = true;
+                    c(procObj);
+                }
+            });
+
+            child.on('error', function(e) {
+                TRACE_PROCESS("process errored:", e);
+                if(!spawned) {
+                    // if the process hasn't spawned yet we can raise an exception
+                    // immediately
+
+                    // prevent subsequent calls to the continuation
+                    spawned = true;
+
+                    h$setErrno(e);
+                    c(null);
+                } else {
+                    /*
+                       Convert the node.js status code string to the appropriate
+                       (emscripten SDK) numeric error code.
+
+                       We should add a way to get the error code from the
+                       string without modifying the global h$errno value
+                     */
+                    var currentErrno = h$errno;
+                    h$setErrno(e.code);
+                    var code = h$errno;
+                    h$errno = currentErrno;
+
+                    procObj.exit = code;
+                    for(var i=0;i<procObj.waiters.length;i++) {
+                        procObj.waiters[i](code);
+                    }
+                }
+            });
+
+            procObj = {  fds: [ stdin_fd  === -1 ? h$process_pipeFd(child.stdio[0], true)  : null
+                              , stdout_fd === -1 ? h$process_pipeFd(child.stdio[1], false) : null
+                              , stderr_fd === -1 ? h$process_pipeFd(child.stdio[2], false) : null
+                              ]
+                        , exit: null
+                        , waiters : []
+                        , child: child
+                    };
+            TRACE_PROCESS("process object created:", procObj);
+
+            // sometimes the process has already spawned before we attach the 'spawn` event handler,
+            // check here if it already has a pid and immediately call the continuation if that's the
+            // case
+            if(typeof child.pid === 'number') {
+                TRACE_PROCESS("process spawned immediately", child.pid);
+
+                spawned = true;
+                c(procObj);
+            }
+
+        } catch(e) {
+            TRACE_PROCESS("catch:", e);
+            spawned = true;
+            h$setErrno(e);
+            c(null);
+        }
+    } else { // h$isNode
+        h$unsupported(null, c);
+    }
+}
+
+/*
+  return the thing to run as an array, first element the process,
+  followed by the the args. null if no interpreter can be found
+
+    - cmd: string - the command to run
+    - args: array of string - arguments, null to run cmd as a shell command
+              in an interpreter.
+ */
+function h$process_commandToProcess(cmd, args) {
+    if(h$isNode()) {
+        TRACE_PROCESS("commandToProcess: ", cmd, args);
+        if(process.platform === 'win32') {
+            if(args === null) { // shellcmd
+                var com = process.env['COMSPEC'];
+                /*
+                   Note: The old GHCJS code had a fallback using code from
+                         the directory package (h$directory_findExecutables).
+                         Here we just produce an error if COMSPEC is not set,
+                         since we don't have the code from the directory package
+                         available.
+                         If needed we could implement similar functionality here.
+                  */
+                if(!com) {
+                    h$setErrno('ENOENT');
+                    return null;
+                }
+                return [com, " /c " + cmd];
+            } else {
+                var r = [cmd];
+                r = r.concat(args);
+                return r;
+            }
+        } else {  // non-windows
+            if(args === null) { // shellcmd
+                return ["/bin/sh", "-c", cmd];
+            } else {
+                var r = [cmd];
+                r = r.concat(args);
+                return r;
+            }
+        }
+    } else {
+        return h$unsupported(null);
+    }
+}
+/*
+  Send the SIGTERM signal to the child process
+ */
+function h$process_terminateProcess(ph) {
+    TRACE_PROCESS("terminateProcess", ph);
+    if(h$isNode()) {
+        ph.child.kill();
+        return 0;
+    } else {
+        return h$unsupported(1);
+    }
+}
+
+/*
+   Get the process exit code. Does not block.
+
+      - returns 0 if the process has not exited yet.
+      - returns 1 and saves the exit code in the code_d pointer otherwise
+ */
+function h$process_getProcessExitCode(ph, code_d, code_o) {
+    TRACE_PROCESS("getProcessExitCode", ph);
+    if(ph.exit === null) return 0;
+    code_d.i3[code_o>>2] = ph.exit;
+    return 1;
+}
+
+/*
+    Wait for the process to finish and return the exit code.
+ */
+function h$process_waitForProcess(ph, code_d, code_o, c) {
+    TRACE_PROCESS("waitForProcess", ph);
+    if(h$isNode()) {
+        if(ph.exit !== null) {
+            h$process_getProcessExitCode(ph, code_d, code_o);
+            c(0);
+        } else {
+            ph.waiters.push(function(code) {
+		        code_d.i3[code_o>>2] = code;
+		        c(0);
+	        });
+        }
+    } else {
+        h$unsupported(-1, c);
+    }
+}
+
+function h$process_interruptProcessGroupOf(ph) {
+    TRACE_PROCESS("interruptProcessGroupOf", ph);
+    if(h$isNode()) {
+        // there doesn't appear to be a way to find the process
+        // group id from a process id (ph.child.pid) on nodejs,
+        // so this operation is unsupported.
+        return h$unsupported(-1);
+    } else {
+        return h$unsupported(-1);
+    }
+}
+
+var h$process_delegateControlCCount = 0;
+
+/*
+  We install a signal handler that ignores SIGINT/SIGQUIT while
+  delegating ctl-c handling.
+
+  This keeps the current node.js process running and propagates the
+  signal to the child processes in the same group.
+ */
+function h$process_ignoreSIG() {
+    TRACE_PROCESS("process_ignoreSIG: ignoring signal");
+    return 0;
+}
+
+/*
+   Start delegating ctl-c handling. Installs the above handler if this is the
+   first process for which delegation is needed.
+ */
+function h$process_startDelegateControlC() {
+    TRACE_PROCESS("startDelegateControlC", h$process_delegateControlCCount);
+    if(h$isNode()) {
+        if(h$process_delegateControlCCount === 0) {
+            TRACE_PROCESS("startDelegateControlC: installing handler")
+            process.on('SIGINT', h$process_ignoreSIG);
+            process.on('SIGQUIT', h$process_ignoreSIG);
+
+        }
+        h$process_delegateControlCCount++;
+        return 0;
+    } else {
+        return h$unsupported(-1);
+    }
+}
+
+/*
+   Stop delegating ctrl-c handling. Removes the above handler if this is the
+   last process for which delegation is needed.
+ */
+function h$process_stopDelegateControlC() {
+    TRACE_PROCESS("stopDelegateControlC", h$process_delegateControlCCount);
+    if(h$isNode()) {
+        if(h$process_delegateControlCCount > 0) {
+            h$process_delegateControlCCount--;
+            if(h$process_delegateControlCCount === 0) {
+                TRACE_PROCESS("stopDelegateControlC: removing handler")
+                process.off('SIGINT', h$process_ignoreSIG);
+                process.off('SIGQUIT', h$process_ignoreSIG);
+            }
+        }
+        return 0;
+    } else {
+        return h$unsupported(-1);
+    }
+}
+
+/*
+   Get the process id of the current (node.js) process
+ */
+function h$process_getCurrentProcessId() {
+    TRACE_PROCESS("getCurrentProcessId");
+    if(h$isNode()) {
+        return process.pid;
+    } else {
+        return h$unsupported(-1);
+    }
+}
+
+/*
+   Get the process id of a child process
+ */
+function h$process_getProcessId(ph) {
+    TRACE_PROCESS("getProcessId", ph);
+    if(ph && typeof ph === 'object' &&
+       ph.child && typeof ph.child == 'object' &&
+       typeof ph.child.pid == 'number') {
+        return ph.child.pid;
+    } else {
+        h$setErrno('EBADF');
+        return -1;
+    }
+}
diff --git a/process.cabal b/process.cabal
--- a/process.cabal
+++ b/process.cabal
@@ -1,24 +1,35 @@
+cabal-version: 2.4
 name:          process
-version:       1.3.0.0
+version:       1.6.30.0
 -- NOTE: Don't forget to update ./changelog.md
-license:       BSD3
+license:       BSD-3-Clause
 license-file:  LICENSE
 maintainer:    libraries@haskell.org
 bug-reports:   https://github.com/haskell/process/issues
 synopsis:      Process libraries
 category:      System
 build-type:    Configure
-cabal-version: >=1.10
 description:
     This package contains libraries for dealing with system processes.
+    .
+    The typed-process package is a more recent take on a process API,
+    which uses this package internally. It features better binary
+    support, easier concurrency, and a more composable API. You can
+    read more about it at
+    <https://github.com/fpco/typed-process/#readme>.
 
+extra-doc-files:
+    changelog.md
+
 extra-source-files:
     aclocal.m4
-    changelog.md
     configure
     configure.ac
     include/HsProcessConfig.h.in
     process.buildinfo
+    exes/echo.bat
+    exes/subdir/echo.bat
+    cbits/posix/common.h
 
 extra-tmp-files:
     autom4te.cache
@@ -30,6 +41,11 @@
     type:     git
     location: https://github.com/haskell/process.git
 
+flag os-string
+    description: Use the new os-string package
+    default: False
+    manual: False
+
 library
     default-language: Haskell2010
     other-extensions:
@@ -38,41 +54,65 @@
         InterruptibleFFI
         RecordWildCards
         Trustworthy
-    if impl(ghc>=7.9)
-        other-extensions: Safe
+        Safe
 
     exposed-modules:
         System.Cmd
         System.Process
-    if impl(ghc)
-        exposed-modules:
-            System.Process.Internals
+        System.Process.CommunicationHandle
+        System.Process.CommunicationHandle.Internal
+        System.Process.Environment.OsString
+        System.Process.Internals
+    other-modules: System.Process.Common
+    if os(windows)
+        c-sources:
+            cbits/win32/runProcess.c
+        other-modules: System.Process.Windows
+        build-depends: Win32 >= 2.14.1.0 && < 2.15
+        -- ole32 and rpcrt4 are needed to create GUIDs for unique named pipes
+        -- for process.
+        extra-libraries: kernel32, ole32, rpcrt4
+        cpp-options: -DWINDOWS
+    else
+        build-depends: unix >= 2.8.0.0 && < 2.9
+        if arch(javascript)
+            js-sources:
+                jsbits/process.js
+            other-modules: System.Process.JavaScript
+        else
+            c-sources:
+                cbits/posix/runProcess.c
+                cbits/posix/fork_exec.c
+                cbits/posix/posix_spawn.c
+                cbits/posix/find_executable.c
+            other-modules: System.Process.Posix
 
-    c-sources:
-        cbits/runProcess.c
+    -- On macOS, posix_spawn_file_actions_addchdir is available from macOS >= 26.
+    -- We weakly reference this symbol when we are build on such a platform.
+    -- However, weak references on MachO are hints to the dynamic loader, not the
+    -- static linker, which will still expect the symbol to be defined somewhere.
+    -- This means linking fails when we try to link an executable depending on
+    -- process on a toolchain which doesn't have this symbol against a process
+    -- library build on a toolchain with the symbol.
+    -- See https://github.com/haskell/process/issues/376
+    -- Hence: instruct the linker to explicilty allow undefined references to
+    -- the symbol when linking against process on darwin
+    if os(darwin)
+        ld-options: -Wl,-U,_posix_spawn_file_actions_addchdir
+
     include-dirs: include
-    includes:
-        runProcess.h
     install-includes:
         runProcess.h
         processFlags.h
 
     ghc-options: -Wall
 
-    build-depends: base      >= 4.4 && < 4.9,
-                   directory >= 1.1 && < 1.3,
-                   filepath  >= 1.2 && < 1.5,
-                   deepseq   >= 1.1 && < 1.5
-    if os(windows)
-        build-depends: Win32 >=2.2 && < 2.4
-        extra-libraries: kernel32
-    else
-        build-depends: unix >= 2.5 && < 2.8
+    build-depends: base      >= 4.12.0.0 && < 4.24,
+                   directory >= 1.1 && < 1.4,
+                   deepseq   >= 1.1 && < 1.6
 
-test-suite test
-  default-language: Haskell2010
-  hs-source-dirs: test
-  main-is: main.hs
-  type: exitcode-stdio-1.0
-  build-depends: base
-               , process
+    if flag(os-string)
+        build-depends: filepath >= 1.5.0.0 && < 1.6,
+                       os-string >= 2.0.0 && < 2.1
+    else
+        build-depends: filepath >= 1.4.100.0 && < 1.5.0.0
diff --git a/test/main.hs b/test/main.hs
deleted file mode 100644
--- a/test/main.hs
+++ /dev/null
@@ -1,30 +0,0 @@
-import Control.Exception
-import System.Exit
-import System.IO.Error
-import System.Process
-
-main :: IO ()
-main = do
-    res <- handle (return . Left . isDoesNotExistError) $ do
-        (_, _, _, ph) <- createProcess (proc "definitelydoesnotexist" [])
-            { close_fds = True
-            }
-        fmap Right $ waitForProcess ph
-    case res of
-        Left True -> return ()
-        _ -> error $ show res
-
-    let test name modifier = do
-            putStrLn $ "Running test: " ++ name
-            (_, _, _, ph) <- createProcess
-                $ modifier $ proc "echo" ["hello", "world"]
-            ec <- waitForProcess ph
-            if ec == ExitSuccess
-                then putStrLn $ "Success running: " ++ name
-                else error $ "echo returned: " ++ show ec
-
-    test "detach_console" $ \cp -> cp { detach_console = True }
-    test "create_new_console" $ \cp -> cp { create_new_console = True }
-    test "new_session" $ \cp -> cp { new_session = True }
-
-    putStrLn "Tests passed successfully"
