// Written in the D programming language.

/**
Functions for starting and interacting with other processes, and for
working with the current process' execution environment.

Process_handling:
$(UL $(LI
    $(LREF spawnProcess) spawns a new process, optionally assigning it an
    arbitrary set of standard input, output, and error streams.
    The function returns immediately, leaving the child process to execute
    in parallel with its parent.  All other functions in this module that
    spawn processes are built around `spawnProcess`.)
$(LI
    $(LREF wait) makes the parent process wait for a child process to
    terminate.  In general one should always do this, to avoid
    child processes becoming "zombies" when the parent process exits.
    Scope guards are perfect for this – see the $(LREF spawnProcess)
    documentation for examples.  $(LREF tryWait) is similar to `wait`,
    but does not block if the process has not yet terminated.)
$(LI
    $(LREF pipeProcess) also spawns a child process which runs
    in parallel with its parent.  However, instead of taking
    arbitrary streams, it automatically creates a set of
    pipes that allow the parent to communicate with the child
    through the child's standard input, output, and/or error streams.
    This function corresponds roughly to C's `popen` function.)
$(LI
    $(LREF execute) starts a new process and waits for it
    to complete before returning.  Additionally, it captures
    the process' standard output and error streams and returns
    the output of these as a string.)
$(LI
    $(LREF spawnShell), $(LREF pipeShell) and $(LREF executeShell) work like
    `spawnProcess`, `pipeProcess` and `execute`, respectively,
    except that they take a single command string and run it through
    the current user's default command interpreter.
    `executeShell` corresponds roughly to C's `system` function.)
$(LI
    $(LREF kill) attempts to terminate a running process.)
)

The following table compactly summarises the different process creation
functions and how they relate to each other:
$(BOOKTABLE,
    $(TR $(TH )
         $(TH Runs program directly)
         $(TH Runs shell command))
    $(TR $(TD Low-level process creation)
         $(TD $(LREF spawnProcess))
         $(TD $(LREF spawnShell)))
    $(TR $(TD Automatic input/output redirection using pipes)
         $(TD $(LREF pipeProcess))
         $(TD $(LREF pipeShell)))
    $(TR $(TD Execute and wait for completion, collect output)
         $(TD $(LREF execute))
         $(TD $(LREF executeShell)))
)

Other_functionality:
$(UL
$(LI
    $(LREF pipe) is used to create unidirectional pipes.)
$(LI
    $(LREF environment) is an interface through which the current process'
    environment variables can be read and manipulated.)
$(LI
    $(LREF escapeShellCommand) and $(LREF escapeShellFileName) are useful
    for constructing shell command lines in a portable way.)
)

Authors:
    $(LINK2 https://github.com/kyllingstad, Lars Tandle Kyllingstad),
    $(LINK2 https://github.com/schveiguy, Steven Schveighoffer),
    $(HTTP thecybershadow.net, Vladimir Panteleev)
Copyright:
    Copyright (c) 2013, the authors. All rights reserved.
License:
   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
Source:
    $(PHOBOSSRC std/process.d)
Macros:
    OBJECTREF=$(REF1 $0, object)

Note:
Most of the functionality in this module is not available on iOS, tvOS
and watchOS. The only functions available on those platforms are:
$(LREF environment), $(LREF thisProcessID) and $(LREF thisThreadID).
*/
module std.process;

import core.thread : ThreadID;

version (Posix)
{
    import core.sys.posix.sys.wait;
    import core.sys.posix.unistd;
}
version (Windows)
{
    import core.stdc.stdio;
    import core.sys.windows.winbase;
    import core.sys.windows.winnt;
    import std.utf;
    import std.windows.syserror;
}

import std.internal.cstring;
import std.range;
import std.stdio;

version (OSX)
    version = Darwin;
else version (iOS)
{
    version = Darwin;
    version = iOSDerived;
}
else version (TVOS)
{
    version = Darwin;
    version = iOSDerived;
}
else version (WatchOS)
{
    version = Darwin;
    version = iOSDerived;
}

// When the DMC runtime is used, we have to use some custom functions
// to convert between Windows file handles and FILE*s.
version (Win32) version (CRuntime_DigitalMars) version = DMC_RUNTIME;


// Some of the following should be moved to druntime.
private
{
    // Microsoft Visual C Runtime (MSVCRT) declarations.
    version (Windows)
    {
        version (DMC_RUNTIME) { } else
        {
            import core.stdc.stdint;
            enum
            {
                STDIN_FILENO  = 0,
                STDOUT_FILENO = 1,
                STDERR_FILENO = 2,
            }
        }
    }

    // POSIX API declarations.
    version (Posix)
    {
        version (Darwin)
        {
            extern(C) char*** _NSGetEnviron() nothrow;
            const(char**) getEnvironPtr() @trusted
            {
                return *_NSGetEnviron;
            }
        }
        else
        {
            // Made available by the C runtime:
            extern(C) extern __gshared const char** environ;
            const(char**) getEnvironPtr() @trusted
            {
                return environ;
            }
        }

        @system unittest
        {
            import core.thread : Thread;
            new Thread({assert(getEnvironPtr !is null);}).start();
        }
    }
} // private

// =============================================================================
// Environment variable manipulation.
// =============================================================================

/**
Manipulates _environment variables using an associative-array-like
interface.

This class contains only static methods, and cannot be instantiated.
See below for examples of use.
*/
abstract final class environment
{
    static import core.sys.posix.stdlib;
    import core.stdc.errno : errno, EINVAL;

static:
    /**
    Retrieves the value of the environment variable with the given `name`.
    ---
    auto path = environment["PATH"];
    ---

    Throws:
    $(OBJECTREF Exception) if the environment variable does not exist,
    or $(REF UTFException, std,utf) if the variable contains invalid UTF-16
    characters (Windows only).

    See_also:
    $(LREF environment.get), which doesn't throw on failure.
    */
    string opIndex(scope const(char)[] name) @safe
    {
        import std.exception : enforce;
        return get(name, null).enforce("Environment variable not found: "~name);
    }

    /**
    Retrieves the value of the environment variable with the given `name`,
    or a default value if the variable doesn't exist.

    Unlike $(LREF environment.opIndex), this function never throws on Posix.
    ---
    auto sh = environment.get("SHELL", "/bin/sh");
    ---
    This function is also useful in checking for the existence of an
    environment variable.
    ---
    auto myVar = environment.get("MYVAR");
    if (myVar is null)
    {
        // Environment variable doesn't exist.
        // Note that we have to use 'is' for the comparison, since
        // myVar == null is also true if the variable exists but is
        // empty.
    }
    ---
    Params:
        name = name of the environment variable to retrieve
        defaultValue = default value to return if the environment variable doesn't exist.

    Returns:
        the value of the environment variable if found, otherwise
        `null` if the environment doesn't exist.

    Throws:
    $(REF UTFException, std,utf) if the variable contains invalid UTF-16
    characters (Windows only).
    */
    string get(scope const(char)[] name, string defaultValue = null) @safe
    {
        string value;
        getImpl(name, (result) { value = result ? cachedToString(result) : defaultValue; });
        return value;
    }

    /**
    Assigns the given `value` to the environment variable with the given
    `name`.
    If `value` is null the variable is removed from environment.

    If the variable does not exist, it will be created. If it already exists,
    it will be overwritten.
    ---
    environment["foo"] = "bar";
    ---

    Throws:
    $(OBJECTREF Exception) if the environment variable could not be added
        (e.g. if the name is invalid).

    Note:
    On some platforms, modifying environment variables may not be allowed in
    multi-threaded programs. See e.g.
    $(LINK2 https://www.gnu.org/software/libc/manual/html_node/Environment-Access.html#Environment-Access, glibc).
    */
    inout(char)[] opIndexAssign(return scope inout char[] value, scope const(char)[] name) @trusted
    {
        version (Posix)
        {
            import std.exception : enforce, errnoEnforce;
            if (value is null)
            {
                remove(name);
                return value;
            }
            if (core.sys.posix.stdlib.setenv(name.tempCString(), value.tempCString(), 1) != -1)
            {
                return value;
            }
            // The default errno error message is very uninformative
            // in the most common case, so we handle it manually.
            enforce(errno != EINVAL,
                "Invalid environment variable name: '"~name~"'");
            errnoEnforce(false,
                "Failed to add environment variable");
            assert(0);
        }
        else version (Windows)
        {
            import std.windows.syserror : wenforce;
            wenforce(
                SetEnvironmentVariableW(name.tempCStringW(), value.tempCStringW()),
            );
            return value;
        }
        else static assert(0);
    }

    /**
    Removes the environment variable with the given `name`.

    If the variable isn't in the environment, this function returns
    successfully without doing anything.

    Note:
    On some platforms, modifying environment variables may not be allowed in
    multi-threaded programs. See e.g.
    $(LINK2 https://www.gnu.org/software/libc/manual/html_node/Environment-Access.html#Environment-Access, glibc).
    */
    void remove(scope const(char)[] name) @trusted nothrow @nogc
    {
        version (Windows)    SetEnvironmentVariableW(name.tempCStringW(), null);
        else version (Posix) core.sys.posix.stdlib.unsetenv(name.tempCString());
        else static assert(0);
    }

    /**
    Identify whether a variable is defined in the environment.

    Because it doesn't return the value, this function is cheaper than `get`.
    However, if you do need the value as well, you should just check the
    return of `get` for `null` instead of using this function first.

    Example:
    -------------
    // good usage
    if ("MY_ENV_FLAG" in environment)
        doSomething();

    // bad usage
    if ("MY_ENV_VAR" in environment)
        doSomething(environment["MY_ENV_VAR"]);

    // do this instead
    if (auto var = environment.get("MY_ENV_VAR"))
        doSomething(var);
    -------------
    */
    bool opBinaryRight(string op : "in")(scope const(char)[] name) @trusted
    {
        version (Posix)
            return core.sys.posix.stdlib.getenv(name.tempCString()) !is null;
        else version (Windows)
        {
            SetLastError(NO_ERROR);
            if (GetEnvironmentVariableW(name.tempCStringW, null, 0) > 0)
                return true;
            immutable err = GetLastError();
            if (err == NO_ERROR)
                return true; // zero-length environment variable on Wine / XP
            if (err == ERROR_ENVVAR_NOT_FOUND)
                return false;
            // Some other Windows error, throw.
            throw new WindowsException(err);
        }
        else static assert(0);
    }

    /**
    Copies all environment variables into an associative array.

    Windows_specific:
    While Windows environment variable names are case insensitive, D's
    built-in associative arrays are not.  This function will store all
    variable names in uppercase (e.g. `PATH`).

    Throws:
    $(OBJECTREF Exception) if the environment variables could not
        be retrieved (Windows only).
    */
    string[string] toAA() @trusted
    {
        import std.conv : to;
        string[string] aa;
        version (Posix)
        {
            auto environ = getEnvironPtr;
            for (int i=0; environ[i] != null; ++i)
            {
                import std.string : indexOf;

                immutable varDef = to!string(environ[i]);
                immutable eq = indexOf(varDef, '=');
                assert(eq >= 0);

                immutable name = varDef[0 .. eq];
                immutable value = varDef[eq+1 .. $];

                // In POSIX, environment variables may be defined more
                // than once.  This is a security issue, which we avoid
                // by checking whether the key already exists in the array.
                // For more info:
                // http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/environment-variables.html
                if (name !in aa)  aa[name] = value;
            }
        }
        else version (Windows)
        {
            import std.exception : enforce;
            import std.uni : toUpper;
            auto envBlock = GetEnvironmentStringsW();
            enforce(envBlock, "Failed to retrieve environment variables.");
            scope(exit) FreeEnvironmentStringsW(envBlock);

            for (int i=0; envBlock[i] != '\0'; ++i)
            {
                auto start = i;
                while (envBlock[i] != '=') ++i;
                immutable name = toUTF8(toUpper(envBlock[start .. i]));

                start = i+1;
                while (envBlock[i] != '\0') ++i;

                // Ignore variables with empty names. These are used internally
                // by Windows to keep track of each drive's individual current
                // directory.
                if (!name.length)
                    continue;

                // Just like in POSIX systems, environment variables may be
                // defined more than once in an environment block on Windows,
                // and it is just as much of a security issue there.  Moreso,
                // in fact, due to the case insensensitivity of variable names,
                // which is not handled correctly by all programs.
                auto val = toUTF8(envBlock[start .. i]);
                if (name !in aa) aa[name] = val is null ? "" : val;
            }
        }
        else static assert(0);
        return aa;
    }

private:
    version (Windows) alias OSChar = WCHAR;
    else version (Posix) alias OSChar = char;

    // Retrieves the environment variable. Calls `sink` with a
    // temporary buffer of OS characters, or `null` if the variable
    // doesn't exist.
    void getImpl(scope const(char)[] name, scope void delegate(const(OSChar)[]) @safe sink) @trusted
    {
        version (Windows)
        {
            // first we ask windows how long the environment variable is,
            // then we try to read it in to a buffer of that length. Lots
            // of error conditions because the windows API is nasty.

            import std.conv : to;
            const namezTmp = name.tempCStringW();
            WCHAR[] buf;

            // clear error because GetEnvironmentVariable only says it sets it
            // if the environment variable is missing, not on other errors.
            SetLastError(NO_ERROR);
            // len includes terminating null
            immutable len = GetEnvironmentVariableW(namezTmp, null, 0);
            if (len == 0)
            {
                immutable err = GetLastError();
                if (err == ERROR_ENVVAR_NOT_FOUND)
                    return sink(null);
                if (err != NO_ERROR) // Some other Windows error, throw.
                    throw new WindowsException(err);
            }
            if (len <= 1)
                return sink("");
            buf.length = len;

            while (true)
            {
                // lenRead is either the number of bytes read w/o null - if buf was long enough - or
                // the number of bytes necessary *including* null if buf wasn't long enough
                immutable lenRead = GetEnvironmentVariableW(namezTmp, buf.ptr, to!DWORD(buf.length));
                if (lenRead == 0)
                {
                    immutable err = GetLastError();
                    if (err == NO_ERROR) // sucessfully read a 0-length variable
                        return sink("");
                    if (err == ERROR_ENVVAR_NOT_FOUND) // variable didn't exist
                        return sink(null);
                    // some other windows error
                    throw new WindowsException(err);
                }
                assert(lenRead != buf.length, "impossible according to msft docs");
                if (lenRead < buf.length) // the buffer was long enough
                    return sink(buf[0 .. lenRead]);
                // resize and go around again, because the environment variable grew
                buf.length = lenRead;
            }
        }
        else version (Posix)
        {
            import core.stdc.string : strlen;

            const vz = core.sys.posix.stdlib.getenv(name.tempCString());
            if (vz == null) return sink(null);
            return sink(vz[0 .. strlen(vz)]);
       }
        else static assert(0);
    }

    string cachedToString(C)(scope const(C)[] v) @safe
    {
        import std.algorithm.comparison : equal;

        // Cache the last call's result.
        static string lastResult;
        if (v.empty)
        {
            // Return non-null array for blank result to distinguish from
            // not-present result.
            lastResult = "";
        }
        else if (!v.equal(lastResult))
        {
            import std.conv : to;
            lastResult = v.to!string;
        }
        return lastResult;
    }
}

@safe unittest
{
    import std.exception : assertThrown;
    // New variable
    environment["std_process"] = "foo";
    assert(environment["std_process"] == "foo");
    assert("std_process" in environment);

    // Set variable again (also tests length 1 case)
    environment["std_process"] = "b";
    assert(environment["std_process"] == "b");
    assert("std_process" in environment);

    // Remove variable
    environment.remove("std_process");
    assert("std_process" !in environment);

    // Remove again, should succeed
    environment.remove("std_process");
    assert("std_process" !in environment);

    // Throw on not found.
    assertThrown(environment["std_process"]);

    // get() without default value
    assert(environment.get("std_process") is null);

    // get() with default value
    assert(environment.get("std_process", "baz") == "baz");

    // get() on an empty (but present) value
    environment["std_process"] = "";
    auto res = environment.get("std_process");
    assert(res !is null);
    assert(res == "");
    assert("std_process" in environment);

    // Important to do the following round-trip after the previous test
    // because it tests toAA with an empty var

    // Convert to associative array
    auto aa = environment.toAA();
    assert(aa.length > 0);
    foreach (n, v; aa)
    {
        // Wine has some bugs related to environment variables:
        //  - Wine allows the existence of an env. variable with the name
        //    "\0", but GetEnvironmentVariable refuses to retrieve it.
        //    As of 2.067 we filter these out anyway (see comment in toAA).

        assert(v == environment[n]);
    }

    // ... and back again.
    foreach (n, v; aa)
        environment[n] = v;

    // Complete the roundtrip
    auto aa2 = environment.toAA();
    import std.conv : text;
    assert(aa == aa2, text(aa, " != ", aa2));
    assert("std_process" in environment);

    // Setting null must have the same effect as remove
    environment["std_process"] = null;
    assert("std_process" !in environment);
}

// =============================================================================
// Functions and classes for process management.
// =============================================================================

/**
 * Returns the process ID of the current process,
 * which is guaranteed to be unique on the system.
 *
 * Example:
 * ---
 * writefln("Current process ID: %d", thisProcessID);
 * ---
 */
@property int thisProcessID() @trusted nothrow @nogc //TODO: @safe
{
    version (Windows)    return GetCurrentProcessId();
    else version (Posix) return core.sys.posix.unistd.getpid();
}


/**
 * Returns the process ID of the current thread,
 * which is guaranteed to be unique within the current process.
 *
 * Returns:
 * A $(REF ThreadID, core,thread) value for the calling thread.
 *
 * Example:
 * ---
 * writefln("Current thread ID: %s", thisThreadID);
 * ---
 */
@property ThreadID thisThreadID() @trusted nothrow @nogc //TODO: @safe
{
    version (Windows)
        return GetCurrentThreadId();
    else
    version (Posix)
    {
        import core.sys.posix.pthread : pthread_self;
        return pthread_self();
    }
}


@system unittest
{
    int pidA, pidB;
    ThreadID tidA, tidB;
    pidA = thisProcessID;
    tidA = thisThreadID;

    import core.thread;
    auto t = new Thread({
        pidB = thisProcessID;
        tidB = thisThreadID;
    });
    t.start();
    t.join();

    assert(pidA == pidB);
    assert(tidA != tidB);
}


package(std) string uniqueTempPath() @safe
{
    import std.file : tempDir;
    import std.path : buildPath;
    import std.uuid : randomUUID;
    // Path should contain spaces to test escaping whitespace
    return buildPath(tempDir(), "std.process temporary file " ~
        randomUUID().toString());
}


version (iOSDerived) {}
else:

/**
Spawns a new process, optionally assigning it an arbitrary set of standard
input, output, and error streams.

The function returns immediately, leaving the child process to execute
in parallel with its parent.  It is recommended to always call $(LREF wait)
on the returned $(LREF Pid) unless the process was spawned with
`Config.detached` flag, as detailed in the documentation for `wait`.

Command_line:
There are four overloads of this function.  The first two take an array
of strings, `args`, which should contain the program name as the
zeroth element and any command-line arguments in subsequent elements.
The third and fourth versions are included for convenience, and may be
used when there are no command-line arguments.  They take a single string,
`program`, which specifies the program name.

Unless a directory is specified in `args[0]` or `program`,
`spawnProcess` will search for the program in a platform-dependent
manner.  On POSIX systems, it will look for the executable in the
directories listed in the PATH environment variable, in the order
they are listed.  On Windows, it will search for the executable in
the following sequence:
$(OL
    $(LI The directory from which the application loaded.)
    $(LI The current directory for the parent process.)
    $(LI The 32-bit Windows system directory.)
    $(LI The 16-bit Windows system directory.)
    $(LI The Windows directory.)
    $(LI The directories listed in the PATH environment variable.)
)
---
// Run an executable called "prog" located in the current working
// directory:
auto pid = spawnProcess("./prog");
scope(exit) wait(pid);
// We can do something else while the program runs.  The scope guard
// ensures that the process is waited for at the end of the scope.
...

// Run DMD on the file "myprog.d", specifying a few compiler switches:
auto dmdPid = spawnProcess(["dmd", "-O", "-release", "-inline", "myprog.d" ]);
if (wait(dmdPid) != 0)
    writeln("Compilation failed!");
---

Environment_variables:
By default, the child process inherits the environment of the parent
process, along with any additional variables specified in the `env`
parameter.  If the same variable exists in both the parent's environment
and in `env`, the latter takes precedence.

If the $(LREF Config.newEnv) flag is set in `config`, the child
process will $(I not) inherit the parent's environment.  Its entire
environment will then be determined by `env`.
---
wait(spawnProcess("myapp", ["foo" : "bar"], Config.newEnv));
---

Standard_streams:
The optional arguments `stdin`, `stdout` and `stderr` may
be used to assign arbitrary $(REF File, std,stdio) objects as the standard
input, output and error streams, respectively, of the child process.  The
former must be opened for reading, while the latter two must be opened for
writing.  The default is for the child process to inherit the standard
streams of its parent.
---
// Run DMD on the file myprog.d, logging any error messages to a
// file named errors.log.
auto logFile = File("errors.log", "w");
auto pid = spawnProcess(["dmd", "myprog.d"],
                        std.stdio.stdin,
                        std.stdio.stdout,
                        logFile);
if (wait(pid) != 0)
    writeln("Compilation failed. See errors.log for details.");
---

Note that if you pass a `File` object that is $(I not)
one of the standard input/output/error streams of the parent process,
that stream will by default be $(I closed) in the parent process when
this function returns.  See the $(LREF Config) documentation below for
information about how to disable this behaviour.

Beware of buffering issues when passing `File` objects to
`spawnProcess`.  The child process will inherit the low-level raw
read/write offset associated with the underlying file descriptor, but
it will not be aware of any buffered data.  In cases where this matters
(e.g. when a file should be aligned before being passed on to the
child process), it may be a good idea to use unbuffered streams, or at
least ensure all relevant buffers are flushed.

Params:
args    = An array which contains the program name as the zeroth element
          and any command-line arguments in the following elements.
stdin   = The standard input stream of the child process.
          This can be any $(REF File, std,stdio) that is opened for reading.
          By default the child process inherits the parent's input
          stream.
stdout  = The standard output stream of the child process.
          This can be any $(REF File, std,stdio) that is opened for writing.
          By default the child process inherits the parent's output stream.
stderr  = The standard error stream of the child process.
          This can be any $(REF File, std,stdio) that is opened for writing.
          By default the child process inherits the parent's error stream.
env     = Additional environment variables for the child process.
config  = Flags that control process creation. See $(LREF Config)
          for an overview of available flags.
workDir = The working directory for the new process.
          By default the child process inherits the parent's working
          directory.

Returns:
A $(LREF Pid) object that corresponds to the spawned process.

Throws:
$(LREF ProcessException) on failure to start the process.$(BR)
$(REF StdioException, std,stdio) on failure to pass one of the streams
    to the child process (Windows only).$(BR)
$(REF RangeError, core,exception) if `args` is empty.
*/
Pid spawnProcess(scope const(char[])[] args,
                 File stdin = std.stdio.stdin,
                 File stdout = std.stdio.stdout,
                 File stderr = std.stdio.stderr,
                 const string[string] env = null,
                 Config config = Config.none,
                 scope const char[] workDir = null)
    @safe
{
    version (Windows)
    {
        const commandLine = escapeShellArguments(args);
        const program = args.length ? args[0] : null;
        return spawnProcessWin(commandLine, program, stdin, stdout, stderr, env, config, workDir);
    }
    else version (Posix)
    {
        return spawnProcessPosix(args, stdin, stdout, stderr, env, config, workDir);
    }
    else
        static assert(0);
}

/// ditto
Pid spawnProcess(scope const(char[])[] args,
                 const string[string] env,
                 Config config = Config.none,
                 scope const(char)[] workDir = null)
    @trusted // TODO: Should be @safe
{
    return spawnProcess(args,
                        std.stdio.stdin,
                        std.stdio.stdout,
                        std.stdio.stderr,
                        env,
                        config,
                        workDir);
}

/// ditto
Pid spawnProcess(scope const(char)[] program,
                 File stdin = std.stdio.stdin,
                 File stdout = std.stdio.stdout,
                 File stderr = std.stdio.stderr,
                 const string[string] env = null,
                 Config config = Config.none,
                 scope const(char)[] workDir = null)
    @trusted
{
    return spawnProcess((&program)[0 .. 1],
                        stdin, stdout, stderr, env, config, workDir);
}

/// ditto
Pid spawnProcess(scope const(char)[] program,
                 const string[string] env,
                 Config config = Config.none,
                 scope const(char)[] workDir = null)
    @trusted
{
    return spawnProcess((&program)[0 .. 1], env, config, workDir);
}

version (Posix) private enum InternalError : ubyte
{
    noerror,
    exec,
    chdir,
    getrlimit,
    doubleFork,
    malloc,
    preExec,
}

/*
Implementation of spawnProcess() for POSIX.

envz should be a zero-terminated array of zero-terminated strings
on the form "var=value".
*/
version (Posix)
private Pid spawnProcessPosix(scope const(char[])[] args,
                              File stdin,
                              File stdout,
                              File stderr,
                              scope const string[string] env,
                              Config config,
                              scope const(char)[] workDir)
    @trusted // TODO: Should be @safe
{
    import core.exception : RangeError;
    import std.algorithm.searching : any;
    import std.conv : text;
    import std.path : isDirSeparator;
    import std.string : toStringz;

    if (args.empty) throw new RangeError();
    const(char)[] name = args[0];
    if (!any!isDirSeparator(name))
    {
        name = searchPathFor(name);
        if (name is null)
            throw new ProcessException(text("Executable file not found: ", args[0]));
    }

    // Convert program name and arguments to C-style strings.
    auto argz = new const(char)*[args.length+1];
    argz[0] = toStringz(name);
    foreach (i; 1 .. args.length) argz[i] = toStringz(args[i]);
    argz[$-1] = null;

    // Prepare environment.
    auto envz = createEnv(env, !(config.flags & Config.Flags.newEnv));

    // Open the working directory.
    // We use open in the parent and fchdir in the child
    // so that most errors (directory doesn't exist, not a directory)
    // can be propagated as exceptions before forking.
    int workDirFD = -1;
    scope(exit) if (workDirFD >= 0) close(workDirFD);
    if (workDir.length)
    {
        import core.sys.posix.fcntl : open, O_RDONLY, stat_t, fstat, S_ISDIR;
        workDirFD = open(workDir.tempCString(), O_RDONLY);
        if (workDirFD < 0)
            throw ProcessException.newFromErrno("Failed to open working directory");
        stat_t s;
        if (fstat(workDirFD, &s) < 0)
            throw ProcessException.newFromErrno("Failed to stat working directory");
        if (!S_ISDIR(s.st_mode))
            throw new ProcessException("Not a directory: " ~ cast(string) workDir);
    }

    static int getFD(ref File f) { return core.stdc.stdio.fileno(f.getFP()); }

    // Get the file descriptors of the streams.
    // These could potentially be invalid, but that is OK.  If so, later calls
    // to dup2() and close() will just silently fail without causing any harm.
    auto stdinFD  = getFD(stdin);
    auto stdoutFD = getFD(stdout);
    auto stderrFD = getFD(stderr);

    // We don't have direct access to the errors that may happen in a child process.
    // So we use this pipe to deliver them.
    int[2] forkPipe;
    if (core.sys.posix.unistd.pipe(forkPipe) == 0)
        setCLOEXEC(forkPipe[1], true);
    else
        throw ProcessException.newFromErrno("Could not create pipe to check startup of child");
    scope(exit) close(forkPipe[0]);

    /*
    To create detached process, we use double fork technique
    but we don't have a direct access to the second fork pid from the caller side thus use a pipe.
    We also can't reuse forkPipe for that purpose
    because we can't predict the order in which pid and possible error will be written
    since the first and the second forks will run in parallel.
    */
    int[2] pidPipe;
    if (config.flags & Config.Flags.detached)
    {
        if (core.sys.posix.unistd.pipe(pidPipe) != 0)
            throw ProcessException.newFromErrno("Could not create pipe to get process pid");
        setCLOEXEC(pidPipe[1], true);
    }
    scope(exit) if (config.flags & Config.Flags.detached) close(pidPipe[0]);

    static void abortOnError(int forkPipeOut, InternalError errorType, int error) nothrow
    {
        core.sys.posix.unistd.write(forkPipeOut, &errorType, errorType.sizeof);
        core.sys.posix.unistd.write(forkPipeOut, &error, error.sizeof);
        close(forkPipeOut);
        core.sys.posix.unistd._exit(1);
        assert(0);
    }

    void closePipeWriteEnds()
    {
        close(forkPipe[1]);
        if (config.flags & Config.Flags.detached)
            close(pidPipe[1]);
    }

    auto id = core.sys.posix.unistd.fork();
    if (id < 0)
    {
        closePipeWriteEnds();
        throw ProcessException.newFromErrno("Failed to spawn new process");
    }

    void forkChild() nothrow @nogc
    {
        static import core.sys.posix.stdio;

        // Child process

        // no need for the read end of pipe on child side
        if (config.flags & Config.Flags.detached)
            close(pidPipe[0]);
        close(forkPipe[0]);
        immutable forkPipeOut = forkPipe[1];
        immutable pidPipeOut = pidPipe[1];

        // Set the working directory.
        if (workDirFD >= 0)
        {
            if (fchdir(workDirFD) < 0)
            {
                // Fail. It is dangerous to run a program
                // in an unexpected working directory.
                abortOnError(forkPipeOut, InternalError.chdir, .errno);
            }
            close(workDirFD);
        }

        void execProcess()
        {
            // Redirect streams and close the old file descriptors.
            // In the case that stderr is redirected to stdout, we need
            // to backup the file descriptor since stdout may be redirected
            // as well.
            if (stderrFD == STDOUT_FILENO) stderrFD = dup(stderrFD);
            dup2(stdinFD,  STDIN_FILENO);
            dup2(stdoutFD, STDOUT_FILENO);
            dup2(stderrFD, STDERR_FILENO);

            // Ensure that the standard streams aren't closed on execute, and
            // optionally close all other file descriptors.
            setCLOEXEC(STDIN_FILENO, false);
            setCLOEXEC(STDOUT_FILENO, false);
            setCLOEXEC(STDERR_FILENO, false);

            if (!(config.flags & Config.Flags.inheritFDs))
            {
                // NOTE: malloc() and getrlimit() are not on the POSIX async
                // signal safe functions list, but practically this should
                // not be a problem. Java VM and CPython also use malloc()
                // in its own implementation via opendir().
                import core.stdc.stdlib : malloc;
                import core.sys.posix.poll : pollfd, poll, POLLNVAL;
                import core.sys.posix.sys.resource : rlimit, getrlimit, RLIMIT_NOFILE;

                // Get the maximum number of file descriptors that could be open.
                rlimit r;
                if (getrlimit(RLIMIT_NOFILE, &r) != 0)
                {
                    abortOnError(forkPipeOut, InternalError.getrlimit, .errno);
                }
                immutable maxDescriptors = cast(int) r.rlim_cur;

                // The above, less stdin, stdout, and stderr
                immutable maxToClose = maxDescriptors - 3;

                // Call poll() to see which ones are actually open:
                auto pfds = cast(pollfd*) malloc(pollfd.sizeof * maxToClose);
                if (pfds is null)
                {
                    abortOnError(forkPipeOut, InternalError.malloc, .errno);
                }
                foreach (i; 0 .. maxToClose)
                {
                    pfds[i].fd = i + 3;
                    pfds[i].events = 0;
                    pfds[i].revents = 0;
                }
                if (poll(pfds, maxToClose, 0) >= 0)
                {
                    foreach (i; 0 .. maxToClose)
                    {
                        // don't close pipe write end
                        if (pfds[i].fd == forkPipeOut) continue;
                        // POLLNVAL will be set if the file descriptor is invalid.
                        if (!(pfds[i].revents & POLLNVAL)) close(pfds[i].fd);
                    }
                }
                else
                {
                    // Fall back to closing everything.
                    foreach (i; 3 .. maxDescriptors)
                    {
                        if (i == forkPipeOut) continue;
                        close(i);
                    }
                }
            }
            else // This is already done if we don't inherit descriptors.
            {
                // Close the old file descriptors, unless they are
                // either of the standard streams.
                if (stdinFD  > STDERR_FILENO)  close(stdinFD);
                if (stdoutFD > STDERR_FILENO)  close(stdoutFD);
                if (stderrFD > STDERR_FILENO)  close(stderrFD);
            }

            if (config.preExecFunction !is null)
            {
                if (config.preExecFunction() != true)
                {
                    abortOnError(forkPipeOut, InternalError.preExec, .errno);
                }
            }

            // Execute program.
            core.sys.posix.unistd.execve(argz[0], argz.ptr, envz);

            // If execution fails, exit as quickly as possible.
            abortOnError(forkPipeOut, InternalError.exec, .errno);
        }

        if (config.flags & Config.Flags.detached)
        {
            auto secondFork = core.sys.posix.unistd.fork();
            if (secondFork == 0)
            {
                close(pidPipeOut);
                execProcess();
            }
            else if (secondFork == -1)
            {
                auto secondForkErrno = .errno;
                close(pidPipeOut);
                abortOnError(forkPipeOut, InternalError.doubleFork, secondForkErrno);
            }
            else
            {
                core.sys.posix.unistd.write(pidPipeOut, &secondFork, pid_t.sizeof);
                close(pidPipeOut);
                close(forkPipeOut);
                _exit(0);
            }
        }
        else
        {
            execProcess();
        }
    }

    if (id == 0)
    {
        forkChild();
        assert(0);
    }
    else
    {
        closePipeWriteEnds();
        auto status = InternalError.noerror;
        auto readExecResult = core.sys.posix.unistd.read(forkPipe[0], &status, status.sizeof);
        // Save error number just in case if subsequent "waitpid" fails and overrides errno
        immutable lastError = .errno;

        if (config.flags & Config.Flags.detached)
        {
            // Forked child exits right after creating second fork. So it should be safe to wait here.
            import core.sys.posix.sys.wait : waitpid;
            int waitResult;
            waitpid(id, &waitResult, 0);
        }

        if (readExecResult == -1)
            throw ProcessException.newFromErrno(lastError, "Could not read from pipe to get child status");

        bool owned = true;
        if (status != InternalError.noerror)
        {
            int error;
            readExecResult = read(forkPipe[0], &error, error.sizeof);
            string errorMsg;
            final switch (status)
            {
                case InternalError.chdir:
                    errorMsg = "Failed to set working directory";
                    break;
                case InternalError.getrlimit:
                    errorMsg = "getrlimit failed";
                    break;
                case InternalError.exec:
                    errorMsg = "Failed to execute '" ~ cast(string) name ~ "'";
                    break;
                case InternalError.doubleFork:
                    // Can happen only when starting detached process
                    assert(config.flags & Config.Flags.detached);
                    errorMsg = "Failed to fork twice";
                    break;
                case InternalError.malloc:
                    errorMsg = "Failed to allocate memory";
                    break;
                case InternalError.preExec:
                    errorMsg = "Failed to execute preExecFunction";
                    break;
                case InternalError.noerror:
                    assert(false);
            }
            if (readExecResult == error.sizeof)
                throw ProcessException.newFromErrno(error, errorMsg);
            throw new ProcessException(errorMsg);
        }
        else if (config.flags & Config.Flags.detached)
        {
            owned = false;
            if (read(pidPipe[0], &id, id.sizeof) != id.sizeof)
                throw ProcessException.newFromErrno("Could not read from pipe to get detached process id");
        }

        // Parent process:  Close streams and return.
        if (!(config.flags & Config.Flags.retainStdin ) && stdinFD  > STDERR_FILENO
                                            && stdinFD  != getFD(std.stdio.stdin ))
            stdin.close();
        if (!(config.flags & Config.Flags.retainStdout) && stdoutFD > STDERR_FILENO
                                            && stdoutFD != getFD(std.stdio.stdout))
            stdout.close();
        if (!(config.flags & Config.Flags.retainStderr) && stderrFD > STDERR_FILENO
                                            && stderrFD != getFD(std.stdio.stderr))
            stderr.close();
        return new Pid(id, owned);
    }
}

version (Posix)
@system unittest
{
    import std.concurrency : ownerTid, receiveTimeout, send, spawn;
    import std.datetime : seconds;

    sigset_t ss;
    sigemptyset(&ss);
    sigaddset(&ss, SIGINT);
    pthread_sigmask(SIG_BLOCK, &ss, null);

    Config config = {
        preExecFunction: () @trusted @nogc nothrow {
            // Reset signal handlers
            sigset_t ss;
            if (sigfillset(&ss) != 0)
            {
                return false;
            }
            if (sigprocmask(SIG_UNBLOCK, &ss, null) != 0)
            {
                return false;
            }
            return true;
        },
    };

    auto pid = spawnProcess(["sleep", "10000"],
                            std.stdio.stdin,
                            std.stdio.stdout,
                            std.stdio.stderr,
                            null,
                            config,
                            null);
    scope(failure)
    {
        kill(pid, SIGKILL);
        wait(pid);
    }

    // kill the spawned process with SIGINT
    // and send its return code
    spawn((shared Pid pid) {
        auto p = cast() pid;
        kill(p, SIGINT);
        auto code = wait(p);
        assert(code < 0);
        send(ownerTid, code);
    }, cast(shared) pid);

    auto received = receiveTimeout(3.seconds, (int) {});
    assert(received);
}

/*
Implementation of spawnProcess() for Windows.

commandLine must contain the entire command line, properly
quoted/escaped as required by CreateProcessW().

envz must be a pointer to a block of UTF-16 characters on the form
"var1=value1\0var2=value2\0...varN=valueN\0\0".
*/
version (Windows)
private Pid spawnProcessWin(scope const(char)[] commandLine,
                            scope const(char)[] program,
                            File stdin,
                            File stdout,
                            File stderr,
                            scope const string[string] env,
                            Config config,
                            scope const(char)[] workDir)
    @trusted
{
    import core.exception : RangeError;
    import std.conv : text;

    if (commandLine.empty) throw new RangeError("Command line is empty");

    // Prepare environment.
    auto envz = createEnv(env, !(config.flags & Config.Flags.newEnv));

    // Startup info for CreateProcessW().
    STARTUPINFO_W startinfo;
    startinfo.cb = startinfo.sizeof;
    static int getFD(ref File f) { return f.isOpen ? f.fileno : -1; }

    // Extract file descriptors and HANDLEs from the streams and make the
    // handles inheritable.
    static void prepareStream(ref File file, DWORD stdHandle, string which,
                              out int fileDescriptor, out HANDLE handle)
    {
        enum _NO_CONSOLE_FILENO = cast(HANDLE)-2;
        fileDescriptor = getFD(file);
        handle = null;
        if (fileDescriptor >= 0)
            handle = file.windowsHandle;
        // Windows GUI applications have a fd but not a valid Windows HANDLE.
        if (handle is null || handle == INVALID_HANDLE_VALUE || handle == _NO_CONSOLE_FILENO)
            handle = GetStdHandle(stdHandle);

        DWORD dwFlags;
        if (GetHandleInformation(handle, &dwFlags))
        {
            if (!(dwFlags & HANDLE_FLAG_INHERIT))
            {
                if (!SetHandleInformation(handle,
                                          HANDLE_FLAG_INHERIT,
                                          HANDLE_FLAG_INHERIT))
                {
                    throw new StdioException(
                        "Failed to make "~which~" stream inheritable by child process ("
                        ~generateSysErrorMsg() ~ ')',
                        0);
                }
            }
        }
    }
    int stdinFD = -1, stdoutFD = -1, stderrFD = -1;
    prepareStream(stdin,  STD_INPUT_HANDLE,  "stdin" , stdinFD,  startinfo.hStdInput );
    prepareStream(stdout, STD_OUTPUT_HANDLE, "stdout", stdoutFD, startinfo.hStdOutput);
    prepareStream(stderr, STD_ERROR_HANDLE,  "stderr", stderrFD, startinfo.hStdError );

    if ((startinfo.hStdInput  != null && startinfo.hStdInput  != INVALID_HANDLE_VALUE)
     || (startinfo.hStdOutput != null && startinfo.hStdOutput != INVALID_HANDLE_VALUE)
     || (startinfo.hStdError  != null && startinfo.hStdError  != INVALID_HANDLE_VALUE))
        startinfo.dwFlags = STARTF_USESTDHANDLES;

    // Create process.
    PROCESS_INFORMATION pi;
    DWORD dwCreationFlags =
        CREATE_UNICODE_ENVIRONMENT |
        ((config.flags & Config.Flags.suppressConsole) ? CREATE_NO_WINDOW : 0);
    // workaround until https://issues.dlang.org/show_bug.cgi?id=14696 is fixed
    auto pworkDir = workDir.tempCStringW();
    if (!CreateProcessW(null, commandLine.tempCStringW().buffPtr,
                        null, null, true, dwCreationFlags,
                        envz, workDir.length ? pworkDir : null, &startinfo, &pi))
        throw ProcessException.newFromLastError("Failed to spawn process \"" ~ cast(string) program ~ '"');

    // figure out if we should close any of the streams
    if (!(config.flags & Config.Flags.retainStdin ) && stdinFD  > STDERR_FILENO
                                        && stdinFD  != getFD(std.stdio.stdin ))
        stdin.close();
    if (!(config.flags & Config.Flags.retainStdout) && stdoutFD > STDERR_FILENO
                                        && stdoutFD != getFD(std.stdio.stdout))
        stdout.close();
    if (!(config.flags & Config.Flags.retainStderr) && stderrFD > STDERR_FILENO
                                        && stderrFD != getFD(std.stdio.stderr))
        stderr.close();

    // close the thread handle in the process info structure
    CloseHandle(pi.hThread);
    if (config.flags & Config.Flags.detached)
    {
        CloseHandle(pi.hProcess);
        return new Pid(pi.dwProcessId);
    }
    return new Pid(pi.dwProcessId, pi.hProcess);
}

// Converts childEnv to a zero-terminated array of zero-terminated strings
// on the form "name=value", optionally adding those of the current process'
// environment strings that are not present in childEnv.  If the parent's
// environment should be inherited without modification, this function
// returns environ directly.
version (Posix)
private const(char*)* createEnv(const string[string] childEnv,
                                bool mergeWithParentEnv)
{
    // Determine the number of strings in the parent's environment.
    int parentEnvLength = 0;
    auto environ = getEnvironPtr;
    if (mergeWithParentEnv)
    {
        if (childEnv.length == 0) return environ;
        while (environ[parentEnvLength] != null) ++parentEnvLength;
    }

    // Convert the "new" variables to C-style strings.
    auto envz = new const(char)*[parentEnvLength + childEnv.length + 1];
    int pos = 0;
    foreach (var, val; childEnv)
        envz[pos++] = (var~'='~val~'\0').ptr;

    // Add the parent's environment.
    foreach (environStr; environ[0 .. parentEnvLength])
    {
        int eqPos = 0;
        while (environStr[eqPos] != '=' && environStr[eqPos] != '\0') ++eqPos;
        if (environStr[eqPos] != '=') continue;
        auto var = environStr[0 .. eqPos];
        if (var in childEnv) continue;
        envz[pos++] = environStr;
    }
    envz[pos] = null;
    return envz.ptr;
}

version (Posix) @system unittest
{
    auto e1 = createEnv(null, false);
    assert(e1 != null && *e1 == null);

    auto e2 = createEnv(null, true);
    assert(e2 != null);
    int i = 0;
    auto environ = getEnvironPtr;
    for (; environ[i] != null; ++i)
    {
        assert(e2[i] != null);
        import core.stdc.string : strcmp;
        assert(strcmp(e2[i], environ[i]) == 0);
    }
    assert(e2[i] == null);

    auto e3 = createEnv(["foo" : "bar", "hello" : "world"], false);
    assert(e3 != null && e3[0] != null && e3[1] != null && e3[2] == null);
    assert((e3[0][0 .. 8] == "foo=bar\0" && e3[1][0 .. 12] == "hello=world\0")
         || (e3[0][0 .. 12] == "hello=world\0" && e3[1][0 .. 8] == "foo=bar\0"));
}


// Converts childEnv to a Windows environment block, which is on the form
// "name1=value1\0name2=value2\0...nameN=valueN\0\0", optionally adding
// those of the current process' environment strings that are not present
// in childEnv.  Returns null if the parent's environment should be
// inherited without modification, as this is what is expected by
// CreateProcess().
version (Windows)
private LPVOID createEnv(const string[string] childEnv,
                         bool mergeWithParentEnv)
{
    if (mergeWithParentEnv && childEnv.length == 0) return null;
    import std.array : appender;
    import std.uni : toUpper;
    auto envz = appender!(wchar[])();
    void put(string var, string val)
    {
        envz.put(var);
        envz.put('=');
        envz.put(val);
        envz.put(cast(wchar) '\0');
    }

    // Add the variables in childEnv, removing them from parentEnv
    // if they exist there too.
    auto parentEnv = mergeWithParentEnv ? environment.toAA() : null;
    foreach (k, v; childEnv)
    {
        auto uk = toUpper(k);
        put(uk, v);
        if (uk in parentEnv) parentEnv.remove(uk);
    }

    // Add remaining parent environment variables.
    foreach (k, v; parentEnv) put(k, v);

    // Two final zeros are needed in case there aren't any environment vars,
    // and the last one does no harm when there are.
    envz.put("\0\0"w);
    return envz.data.ptr;
}

version (Windows) @system unittest
{
    assert(createEnv(null, true) == null);
    assert((cast(wchar*) createEnv(null, false))[0 .. 2] == "\0\0"w);
    auto e1 = (cast(wchar*) createEnv(["foo":"bar", "ab":"c"], false))[0 .. 14];
    assert(e1 == "FOO=bar\0AB=c\0\0"w || e1 == "AB=c\0FOO=bar\0\0"w);
}

// Searches the PATH variable for the given executable file,
// (checking that it is in fact executable).
version (Posix)
package(std) string searchPathFor(scope const(char)[] executable)
    @safe
{
    import std.algorithm.iteration : splitter;
    import std.conv : to;
    import std.path : chainPath;

    typeof(return) result;

    environment.getImpl("PATH",
        (scope const(char)[] path)
        {
            if (!path)
                return;

            foreach (dir; splitter(path, ":"))
            {
                auto execPath = chainPath(dir, executable);
                if (isExecutable(execPath))
                {
                    result = execPath.to!(typeof(result));
                    return;
                }
            }
        });

    return result;
}

// Checks whether the file exists and can be executed by the
// current user.
version (Posix)
private bool isExecutable(R)(R path) @trusted nothrow @nogc
if (isSomeFiniteCharInputRange!R)
{
    return (access(path.tempCString(), X_OK) == 0);
}

version (Posix) @safe unittest
{
    import std.algorithm;
    auto lsPath = searchPathFor("ls");
    assert(!lsPath.empty);
    assert(lsPath[0] == '/');
    assert(lsPath.endsWith("ls"));
    auto unlikely = searchPathFor("lkmqwpoialhggyaofijadsohufoiqezm");
    assert(unlikely is null, "Are you kidding me?");
}

// Sets or unsets the FD_CLOEXEC flag on the given file descriptor.
version (Posix)
private void setCLOEXEC(int fd, bool on) nothrow @nogc
{
    import core.sys.posix.fcntl : fcntl, F_GETFD, FD_CLOEXEC, F_SETFD;
    auto flags = fcntl(fd, F_GETFD);
    if (flags >= 0)
    {
        if (on) flags |= FD_CLOEXEC;
        else    flags &= ~(cast(typeof(flags)) FD_CLOEXEC);
        flags = fcntl(fd, F_SETFD, flags);
    }
    assert(flags != -1 || .errno == EBADF);
}

@system unittest // Command line arguments in spawnProcess().
{
    version (Windows) TestScript prog =
       "if not [%~1]==[foo] ( exit 1 )
        if not [%~2]==[bar] ( exit 2 )
        exit 0";
    else version (Posix) TestScript prog =
       `if test "$1" != "foo"; then exit 1; fi
        if test "$2" != "bar"; then exit 2; fi
        exit 0`;
    assert(wait(spawnProcess(prog.path)) == 1);
    assert(wait(spawnProcess([prog.path])) == 1);
    assert(wait(spawnProcess([prog.path, "foo"])) == 2);
    assert(wait(spawnProcess([prog.path, "foo", "baz"])) == 2);
    assert(wait(spawnProcess([prog.path, "foo", "bar"])) == 0);
}

// test that file descriptors are correctly closed / left open.
// ideally this would be done by the child process making libc
// calls, but we make do...
version (Posix) @system unittest
{
    import core.stdc.errno : errno;
    import core.sys.posix.fcntl : open, O_RDONLY;
    import core.sys.posix.unistd : close;
    import std.algorithm.searching : canFind, findSplitBefore;
    import std.array : split;
    import std.conv : to;
    static import std.file;
    import std.functional : reverseArgs;
    import std.path : buildPath;

    auto directory = uniqueTempPath();
    std.file.mkdir(directory);
    scope(exit) std.file.rmdirRecurse(directory);
    auto path = buildPath(directory, "tmp");
    std.file.write(path, null);
    errno = 0;
    auto fd = open(path.tempCString, O_RDONLY);
    if (fd == -1)
    {
        import core.stdc.string : strerror;
        import std.stdio : stderr;
        import std.string : fromStringz;

        // For the CI logs
        stderr.writefln("%s: could not open '%s': %s",
            __FUNCTION__, path, strerror(errno).fromStringz);
        // TODO: should we retry here instead?
        return;
    }
    scope(exit) close(fd);

    // command >&2 (or any other number) checks whethether that number
    // file descriptor is open.
    // Can't use this for arbitrary descriptors as many shells only support
    // single digit fds.
    TestScript testDefaults = `command >&0 && command >&1 && command >&2`;
    assert(execute(testDefaults.path).status == 0);
    assert(execute(testDefaults.path, null, Config.inheritFDs).status == 0);

    // Try a few different methods to check whether there are any
    // incorrectly-open files.
    void testFDs()
    {
        // try /proc/<pid>/fd/ on linux
        version (linux)
        {
            TestScript proc = "ls /proc/$$/fd";
            auto procRes = execute(proc.path, null);
            if (procRes.status == 0)
            {
                auto fdStr = fd.to!string;
                assert(!procRes.output.split.canFind(fdStr));
                assert(execute(proc.path, null, Config.inheritFDs)
                        .output.split.canFind(fdStr));
                return;
            }
        }

        // try fuser (might sometimes need permissions)
        TestScript fuser = "echo $$ && fuser -f " ~ path;
        auto fuserRes = execute(fuser.path, null);
        if (fuserRes.status == 0)
        {
            assert(!reverseArgs!canFind(fuserRes
                        .output.findSplitBefore("\n").expand));
            assert(reverseArgs!canFind(execute(fuser.path, null, Config.inheritFDs)
                        .output.findSplitBefore("\n").expand));
            return;
        }

        // last resort, try lsof (not available on all Posix)
        TestScript lsof = "lsof -p$$";
        auto lsofRes = execute(lsof.path, null);
        if (lsofRes.status == 0)
        {
            assert(!lsofRes.output.canFind(path));
            auto lsofOut = execute(lsof.path, null, Config.inheritFDs).output;
            if (!lsofOut.canFind(path))
            {
                std.stdio.stderr.writeln(__FILE__, ':', __LINE__,
                    ": Warning: unexpected lsof output:", lsofOut);
            }
            return;
        }

        std.stdio.stderr.writeln(__FILE__, ':', __LINE__,
                ": Warning: Couldn't find any way to check open files");
    }
    testFDs();
}

@system unittest // Environment variables in spawnProcess().
{
    // We really should use set /a on Windows, but Wine doesn't support it.
    version (Windows) TestScript envProg =
       `if [%STD_PROCESS_UNITTEST1%] == [1] (
            if [%STD_PROCESS_UNITTEST2%] == [2] (exit 3)
            exit 1
        )
        if [%STD_PROCESS_UNITTEST1%] == [4] (
            if [%STD_PROCESS_UNITTEST2%] == [2] (exit 6)
            exit 4
        )
        if [%STD_PROCESS_UNITTEST2%] == [2] (exit 2)
        exit 0`;
    version (Posix) TestScript envProg =
       `if test "$std_process_unittest1" = ""; then
            std_process_unittest1=0
        fi
        if test "$std_process_unittest2" = ""; then
            std_process_unittest2=0
        fi
        exit $(($std_process_unittest1+$std_process_unittest2))`;

    environment.remove("std_process_unittest1"); // Just in case.
    environment.remove("std_process_unittest2");
    assert(wait(spawnProcess(envProg.path)) == 0);
    assert(wait(spawnProcess(envProg.path, null, Config.newEnv)) == 0);

    environment["std_process_unittest1"] = "1";
    assert(wait(spawnProcess(envProg.path)) == 1);
    assert(wait(spawnProcess(envProg.path, null, Config.newEnv)) == 0);

    auto env = ["std_process_unittest2" : "2"];
    assert(wait(spawnProcess(envProg.path, env)) == 3);
    assert(wait(spawnProcess(envProg.path, env, Config.newEnv)) == 2);

    env["std_process_unittest1"] = "4";
    assert(wait(spawnProcess(envProg.path, env)) == 6);
    assert(wait(spawnProcess(envProg.path, env, Config.newEnv)) == 6);

    environment.remove("std_process_unittest1");
    assert(wait(spawnProcess(envProg.path, env)) == 6);
    assert(wait(spawnProcess(envProg.path, env, Config.newEnv)) == 6);
}

@system unittest // Stream redirection in spawnProcess().
{
    import std.path : buildPath;
    import std.string;
    version (Windows) TestScript prog =
       "set /p INPUT=
        echo %INPUT% output %~1
        echo %INPUT% error %~2 1>&2
        echo done > %3";
    else version (Posix) TestScript prog =
       "read INPUT
        echo $INPUT output $1
        echo $INPUT error $2 >&2
        echo done > \"$3\"";

    // Pipes
    void testPipes(Config config)
    {
        import std.file : tempDir, exists, remove;
        import std.uuid : randomUUID;
        import std.exception : collectException;
        auto pipei = pipe();
        auto pipeo = pipe();
        auto pipee = pipe();
        auto done = buildPath(tempDir(), randomUUID().toString());
        auto pid = spawnProcess([prog.path, "foo", "bar", done],
                                    pipei.readEnd, pipeo.writeEnd, pipee.writeEnd, null, config);
        pipei.writeEnd.writeln("input");
        pipei.writeEnd.flush();
        assert(pipeo.readEnd.readln().chomp() == "input output foo");
        assert(pipee.readEnd.readln().chomp().stripRight() == "input error bar");
        if (config.flags & Config.Flags.detached)
            while (!done.exists) Thread.sleep(10.msecs);
        else
            wait(pid);
        while (remove(done).collectException) Thread.sleep(10.msecs);
    }

    // Files
    void testFiles(Config config)
    {
        import std.ascii : newline;
        import std.file : tempDir, exists, remove, readText, write;
        import std.uuid : randomUUID;
        import std.exception : collectException;
        auto pathi = buildPath(tempDir(), randomUUID().toString());
        auto patho = buildPath(tempDir(), randomUUID().toString());
        auto pathe = buildPath(tempDir(), randomUUID().toString());
        write(pathi, "INPUT" ~ newline);
        auto filei = File(pathi, "r");
        auto fileo = File(patho, "w");
        auto filee = File(pathe, "w");
        auto done = buildPath(tempDir(), randomUUID().toString());
        auto pid = spawnProcess([prog.path, "bar", "baz", done], filei, fileo, filee, null, config);
        if (config.flags & Config.Flags.detached)
            while (!done.exists) Thread.sleep(10.msecs);
        else
            wait(pid);
        assert(readText(patho).chomp() == "INPUT output bar");
        assert(readText(pathe).chomp().stripRight() == "INPUT error baz");
        while (remove(pathi).collectException) Thread.sleep(10.msecs);
        while (remove(patho).collectException) Thread.sleep(10.msecs);
        while (remove(pathe).collectException) Thread.sleep(10.msecs);
        while (remove(done).collectException) Thread.sleep(10.msecs);
    }

    testPipes(Config.none);
    testFiles(Config.none);
    testPipes(Config.detached);
    testFiles(Config.detached);
}

@system unittest // Error handling in spawnProcess()
{
    import std.algorithm.searching : canFind;
    import std.exception : assertThrown, collectExceptionMsg;

    static void testNotFoundException(string program)
    {
        assert(collectExceptionMsg!ProcessException(spawnProcess(program)).canFind(program));
        assert(collectExceptionMsg!ProcessException(spawnProcess(program, null, Config.detached)).canFind(program));
    }
    testNotFoundException("ewrgiuhrifuheiohnmnvqweoijwf");
    testNotFoundException("./rgiuhrifuheiohnmnvqweoijwf");

    // can't execute malformed file with executable permissions
    version (Posix)
    {
        import std.path : buildPath;
        import std.file : remove, write, setAttributes, tempDir;
        import core.sys.posix.sys.stat : S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IXGRP, S_IROTH, S_IXOTH;
        import std.conv : to;
        string deleteme = buildPath(tempDir(), "deleteme.std.process.unittest.pid") ~ to!string(thisProcessID);
        write(deleteme, "");
        scope(exit) remove(deleteme);
        setAttributes(deleteme, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
        assertThrown!ProcessException(spawnProcess(deleteme));
        assertThrown!ProcessException(spawnProcess(deleteme, null, Config.detached));
    }
}

@system unittest // Specifying a working directory.
{
    import std.path;
    import std.file;
    TestScript prog = "echo foo>bar";

    auto directory = uniqueTempPath();
    mkdir(directory);
    scope(exit) rmdirRecurse(directory);

    auto pid = spawnProcess([prog.path], null, Config.none, directory);
    wait(pid);
    assert(exists(buildPath(directory, "bar")));
}

@system unittest // Specifying a bad working directory.
{
    import std.exception : assertThrown;
    import std.file;
    TestScript prog = "echo";

    auto directory = uniqueTempPath();
    assertThrown!ProcessException(spawnProcess([prog.path], null, Config.none, directory));
    assertThrown!ProcessException(spawnProcess([prog.path], null, Config.detached, directory));

    std.file.write(directory, "foo");
    scope(exit) remove(directory);
    assertThrown!ProcessException(spawnProcess([prog.path], null, Config.none, directory));
    assertThrown!ProcessException(spawnProcess([prog.path], null, Config.detached, directory));

    // can't run in directory if user does not have search permission on this directory
    version (Posix)
    {
        if (core.sys.posix.unistd.getuid() != 0)
        {
            import core.sys.posix.sys.stat : S_IRUSR;
            auto directoryNoSearch = uniqueTempPath();
            mkdir(directoryNoSearch);
            scope(exit) rmdirRecurse(directoryNoSearch);
            setAttributes(directoryNoSearch, S_IRUSR);
            assertThrown!ProcessException(spawnProcess(prog.path, null, Config.none, directoryNoSearch));
            assertThrown!ProcessException(spawnProcess(prog.path, null, Config.detached, directoryNoSearch));
        }
    }
}

@system unittest // Specifying empty working directory.
{
    TestScript prog = "";

    string directory = "";
    assert(directory.ptr && !directory.length);
    spawnProcess([prog.path], null, Config.none, directory).wait();
}

// Reopening the standard streams (https://issues.dlang.org/show_bug.cgi?id=13258)
@system unittest
{
    import std.string;
    import std.file;
    void fun()
    {
        spawnShell("echo foo").wait();
        spawnShell("echo bar").wait();
    }

    auto tmpFile = uniqueTempPath();
    scope(exit) if (exists(tmpFile)) remove(tmpFile);

    {
        auto oldOut = std.stdio.stdout;
        scope(exit) std.stdio.stdout = oldOut;

        std.stdio.stdout = File(tmpFile, "w");
        fun();
        std.stdio.stdout.close();
    }

    auto lines = readText(tmpFile).splitLines();
    assert(lines == ["foo", "bar"]);
}

// MSVCRT workaround (https://issues.dlang.org/show_bug.cgi?id=14422)
version (Windows)
@system unittest
{
    auto fn = uniqueTempPath();
    scope(exit) if (exists(fn)) remove(fn);
    std.file.write(fn, "AAAAAAAAAA");

    auto f = File(fn, "a");
    spawnProcess(["cmd", "/c", "echo BBBBB"], std.stdio.stdin, f).wait();

    auto data = readText(fn);
    assert(data == "AAAAAAAAAABBBBB\r\n", data);
}

// https://issues.dlang.org/show_bug.cgi?id=20765
// Test that running processes with relative path works in conjunction
// with indicating a workDir.
version (Posix) @system unittest
{
    import std.file : mkdir, write, setAttributes, rmdirRecurse;
    import std.conv : octal;

    auto dir = uniqueTempPath();
    mkdir(dir);
    scope(exit) rmdirRecurse(dir);
    write(dir ~ "/program", "#!/bin/sh\necho Hello");
    setAttributes(dir ~ "/program", octal!700);

    assert(execute(["./program"], null, Config.none, size_t.max, dir).output == "Hello\n");
}

/**
A variation on $(LREF spawnProcess) that runs the given _command through
the current user's preferred _command interpreter (aka. shell).

The string `command` is passed verbatim to the shell, and is therefore
subject to its rules about _command structure, argument/filename quoting
and escaping of special characters.
The path to the shell executable defaults to $(LREF nativeShell).

In all other respects this function works just like `spawnProcess`.
Please refer to the $(LREF spawnProcess) documentation for descriptions
of the other function parameters, the return value and any exceptions
that may be thrown.
---
// Run the command/program "foo" on the file named "my file.txt", and
// redirect its output into foo.log.
auto pid = spawnShell(`foo "my file.txt" > foo.log`);
wait(pid);
---

See_also:
$(LREF escapeShellCommand), which may be helpful in constructing a
properly quoted and escaped shell _command line for the current platform.
*/
Pid spawnShell(scope const(char)[] command,
               File stdin = std.stdio.stdin,
               File stdout = std.stdio.stdout,
               File stderr = std.stdio.stderr,
               scope const string[string] env = null,
               Config config = Config.none,
               scope const(char)[] workDir = null,
               scope string shellPath = nativeShell)
    @trusted // See reason below
{
    version (Windows)
    {
        // CMD does not parse its arguments like other programs.
        // It does not use CommandLineToArgvW.
        // Instead, it treats the first and last quote specially.
        // See CMD.EXE /? for details.
        const commandLine = escapeShellFileName(shellPath)
                            ~ ` ` ~ shellSwitch ~ ` "` ~ command ~ `"`;
        return spawnProcessWin(commandLine, shellPath, stdin, stdout, stderr, env, config, workDir);
    }
    else version (Posix)
    {
        const(char)[][3] args;
        args[0] = shellPath;
        args[1] = shellSwitch;
        args[2] = command;
        /* The passing of args converts the static array, which is initialized with `scope` pointers,
         * to a dynamic array, which is also a scope parameter. So, it is a scope pointer to a
         * scope pointer, which although is safely used here, D doesn't allow transitive scope.
         * See https://github.com/dlang/dmd/pull/10951
         */
        return spawnProcessPosix(args, stdin, stdout, stderr, env, config, workDir);
    }
    else
        static assert(0);
}

/// ditto
Pid spawnShell(scope const(char)[] command,
               scope const string[string] env,
               Config config = Config.none,
               scope const(char)[] workDir = null,
               scope string shellPath = nativeShell)
    @trusted // TODO: Should be @safe
{
    return spawnShell(command,
                      std.stdio.stdin,
                      std.stdio.stdout,
                      std.stdio.stderr,
                      env,
                      config,
                      workDir,
                      shellPath);
}

@system unittest
{
    version (Windows)
        auto cmd = "echo %FOO%";
    else version (Posix)
        auto cmd = "echo $foo";
    import std.file;
    auto tmpFile = uniqueTempPath();
    scope(exit) if (exists(tmpFile)) remove(tmpFile);
    auto redir = "> \""~tmpFile~'"';
    auto env = ["foo" : "bar"];
    assert(wait(spawnShell(cmd~redir, env)) == 0);
    auto f = File(tmpFile, "a");
    version (CRuntime_Microsoft) f.seek(0, SEEK_END); // MSVCRT probably seeks to the end when writing, not before
    assert(wait(spawnShell(cmd, std.stdio.stdin, f, std.stdio.stderr, env)) == 0);
    f.close();
    auto output = std.file.readText(tmpFile);
    assert(output == "bar\nbar\n" || output == "bar\r\nbar\r\n");
}

version (Windows)
@system unittest
{
    import std.string;
    import std.conv : text;
    TestScript prog = "echo %0 %*";
    auto outputFn = uniqueTempPath();
    scope(exit) if (exists(outputFn)) remove(outputFn);
    auto args = [`a b c`, `a\b\c\`, `a"b"c"`];
    auto result = executeShell(
        escapeShellCommand([prog.path] ~ args)
        ~ " > " ~
        escapeShellFileName(outputFn));
    assert(result.status == 0);
    auto args2 = outputFn.readText().strip().parseCommandLine()[1..$];
    assert(args == args2, text(args2));
}


/**
Options that control the behaviour of process creation functions in this
module. Most options only apply to $(LREF spawnProcess) and
$(LREF spawnShell).

Example:
---
auto logFile = File("myapp_error.log", "w");

// Start program, suppressing the console window (Windows only),
// redirect its error stream to logFile, and leave logFile open
// in the parent process as well.
auto pid = spawnProcess("myapp", stdin, stdout, logFile,
                        Config.retainStderr | Config.suppressConsole);
scope(exit)
{
    auto exitCode = wait(pid);
    logFile.writeln("myapp exited with code ", exitCode);
    logFile.close();
}
---
*/
struct Config
{
    /**
       Flag options.
       Use bitwise OR to combine flags.
    **/
    enum Flags
    {
        none = 0,

        /**
        By default, the child process inherits the parent's environment,
        and any environment variables passed to $(LREF spawnProcess) will
        be added to it.  If this flag is set, the only variables in the
        child process' environment will be those given to spawnProcess.
        */
        newEnv = 1,

        /**
        Unless the child process inherits the standard input/output/error
        streams of its parent, one almost always wants the streams closed
        in the parent when $(LREF spawnProcess) returns.  Therefore, by
        default, this is done.  If this is not desirable, pass any of these
        options to spawnProcess.
        */
        retainStdin  = 2,
        retainStdout = 4,                                  /// ditto
        retainStderr = 8,                                  /// ditto

        /**
        On Windows, if the child process is a console application, this
        flag will prevent the creation of a console window.  Otherwise,
        it will be ignored. On POSIX, `suppressConsole` has no effect.
        */
        suppressConsole = 16,

        /**
        On POSIX, open $(LINK2 http://en.wikipedia.org/wiki/File_descriptor,file descriptors)
        are by default inherited by the child process.  As this may lead
        to subtle bugs when pipes or multiple threads are involved,
        $(LREF spawnProcess) ensures that all file descriptors except the
        ones that correspond to standard input/output/error are closed
        in the child process when it starts.  Use `inheritFDs` to prevent
        this.

        On Windows, this option has no effect, and any handles which have been
        explicitly marked as inheritable will always be inherited by the child
        process.
        */
        inheritFDs = 32,

        /**
        Spawn process in detached state. This removes the need in calling
        $(LREF wait) to clean up the process resources.

        Note:
        Calling $(LREF wait) or $(LREF kill) with the resulting `Pid` is invalid.
        */
        detached = 64,

        /**
        By default, the $(LREF execute) and $(LREF executeShell) functions
        will capture child processes' both stdout and stderr. This can be
        undesirable if the standard output is to be processed or otherwise
        used by the invoking program, as `execute`'s result would then
        contain a mix of output and warning/error messages.

        Specify this flag when calling `execute` or `executeShell` to
        cause invoked processes' stderr stream to be sent to $(REF stderr,
        std,stdio), and only capture and return standard output.

        This flag has no effect on $(LREF spawnProcess) or $(LREF spawnShell).
        */
        stderrPassThrough = 128,
    }
    Flags flags; /// ditto

    /**
       For backwards compatibility, and cases when only flags need to
       be specified in the `Config`, these allow building `Config`
       instances using flag names only.
    */
    enum Config none = Config.init;
    enum Config newEnv = Config(Flags.newEnv); /// ditto
    enum Config retainStdin = Config(Flags.retainStdin); /// ditto
    enum Config retainStdout = Config(Flags.retainStdout); /// ditto
    enum Config retainStderr = Config(Flags.retainStderr); /// ditto
    enum Config suppressConsole = Config(Flags.suppressConsole); /// ditto
    enum Config inheritFDs = Config(Flags.inheritFDs); /// ditto
    enum Config detached = Config(Flags.detached); /// ditto
    enum Config stderrPassThrough = Config(Flags.stderrPassThrough); /// ditto
    Config opUnary(string op)()
    if (is(typeof(mixin(op ~ q{flags}))))
    {
        return Config(mixin(op ~ q{flags}));
    } /// ditto
    Config opBinary(string op)(Config other)
    if (is(typeof(mixin(q{flags} ~ op ~ q{other.flags}))))
    {
        return Config(mixin(q{flags} ~ op ~ q{other.flags}));
    } /// ditto
    Config opOpAssign(string op)(Config other)
    if (is(typeof(mixin(q{flags} ~ op ~ q{=other.flags}))))
    {
        return Config(mixin(q{flags} ~ op ~ q{=other.flags}));
    } /// ditto

    version (StdDdoc)
    {
        /**
        A function that is called before `exec` in $(LREF spawnProcess).
        It returns `true` if succeeded and otherwise returns `false`.

        $(RED Warning:
            Please note that the code in this function must only use
            async-signal-safe functions.)

        On Windows, this member is not available.
        */
        bool function() nothrow @nogc @safe preExecFunction;
    }
    else version (Posix)
    {
        bool function() nothrow @nogc @safe preExecFunction;
    }
}

// https://issues.dlang.org/show_bug.cgi?id=22125
@safe unittest
{
    Config c = Config.retainStdin;
    c |= Config.retainStdout;
    c |= Config.retainStderr;
    c &= ~Config.retainStderr;
    assert(c == (Config.retainStdin | Config.retainStdout));
}

/// A handle that corresponds to a spawned process.
final class Pid
{
    /**
    The process ID number.

    This is a number that uniquely identifies the process on the operating
    system, for at least as long as the process is running.  Once $(LREF wait)
    has been called on the $(LREF Pid), this method will return an
    invalid (negative) process ID.
    */
    @property int processID() const @safe pure nothrow
    {
        return _processID;
    }

    /**
    An operating system handle to the process.

    This handle is used to specify the process in OS-specific APIs.
    On POSIX, this function returns a `core.sys.posix.sys.types.pid_t`
    with the same value as $(LREF Pid.processID), while on Windows it returns
    a `core.sys.windows.windows.HANDLE`.

    Once $(LREF wait) has been called on the $(LREF Pid), this method
    will return an invalid handle.
    */
    // Note: Since HANDLE is a reference, this function cannot be const.
    version (Windows)
    @property HANDLE osHandle() @nogc @safe pure nothrow
    {
        return _handle;
    }
    else version (Posix)
    @property pid_t osHandle() @nogc @safe pure nothrow
    {
        return _processID;
    }

private:
    /*
    Pid.performWait() does the dirty work for wait() and nonBlockingWait().

    If block == true, this function blocks until the process terminates,
    sets _processID to terminated, and returns the exit code or terminating
    signal as described in the wait() documentation.

    If block == false, this function returns immediately, regardless
    of the status of the process.  If the process has terminated, the
    function has the exact same effect as the blocking version.  If not,
    it returns 0 and does not modify _processID.
    */
    version (Posix)
    int performWait(bool block) @trusted
    {
        import std.exception : enforce;
        enforce!ProcessException(owned, "Can't wait on a detached process");
        if (_processID == terminated) return _exitCode;
        int exitCode;
        while (true)
        {
            int status;
            auto check = waitpid(_processID, &status, block ? 0 : WNOHANG);
            if (check == -1)
            {
                if (errno == ECHILD)
                {
                    throw new ProcessException(
                        "Process does not exist or is not a child process.");
                }
                else
                {
                    // waitpid() was interrupted by a signal.  We simply
                    // restart it.
                    assert(errno == EINTR);
                    continue;
                }
            }
            if (!block && check == 0) return 0;
            if (WIFEXITED(status))
            {
                exitCode = WEXITSTATUS(status);
                break;
            }
            else if (WIFSIGNALED(status))
            {
                exitCode = -WTERMSIG(status);
                break;
            }
            // We check again whether the call should be blocking,
            // since we don't care about other status changes besides
            // "exited" and "terminated by signal".
            if (!block) return 0;

            // Process has stopped, but not terminated, so we continue waiting.
        }
        // Mark Pid as terminated, and cache and return exit code.
        _processID = terminated;
        _exitCode = exitCode;
        return exitCode;
    }
    else version (Windows)
    {
        int performWait(const bool block, const DWORD timeout = INFINITE) @trusted
        {
            import std.exception : enforce;
            enforce!ProcessException(owned, "Can't wait on a detached process");
            if (_processID == terminated) return _exitCode;
            assert(_handle != INVALID_HANDLE_VALUE);
            if (block)
            {
                auto result = WaitForSingleObject(_handle, timeout);
                if (result != WAIT_OBJECT_0)
                {
                    // Wait time exceeded `timeout` milliseconds?
                    if (result == WAIT_TIMEOUT && timeout != INFINITE)
                        return 0;

                    throw ProcessException.newFromLastError("Wait failed.");
                }
            }
            if (!GetExitCodeProcess(_handle, cast(LPDWORD)&_exitCode))
                throw ProcessException.newFromLastError();
            if (!block && _exitCode == STILL_ACTIVE) return 0;
            CloseHandle(_handle);
            _handle = INVALID_HANDLE_VALUE;
            _processID = terminated;
            return _exitCode;
        }

        int performWait(Duration timeout) @safe
        {
            import std.exception : enforce;
            const msecs = timeout.total!"msecs";

            // Limit this implementation the maximum wait time offered by
            // WaitForSingleObject. One could theoretically break up larger
            // durations into multiple waits but (DWORD.max - 1).msecs
            // (> 7 weeks, 17 hours) should be enough for the usual case.
            // DWORD.max is reserved for INFINITE
            enforce!ProcessException(msecs < DWORD.max, "Timeout exceeds maximum wait time!");
            return performWait(true, cast(DWORD) msecs);
        }

        ~this()
        {
            if (_handle != INVALID_HANDLE_VALUE)
            {
                CloseHandle(_handle);
                _handle = INVALID_HANDLE_VALUE;
            }
        }
    }

    // Special values for _processID.
    enum invalid = -1, terminated = -2;

    // OS process ID number.  Only nonnegative IDs correspond to
    // running processes.
    int _processID = invalid;

    // Exit code cached by wait().  This is only expected to hold a
    // sensible value if _processID == terminated.
    int _exitCode;

    // Whether the process can be waited for by wait() for or killed by kill().
    // False if process was started as detached. True otherwise.
    bool owned;

    // Pids are only meant to be constructed inside this module, so
    // we make the constructor private.
    version (Windows)
    {
        HANDLE _handle = INVALID_HANDLE_VALUE;
        this(int pid, HANDLE handle) @safe pure nothrow
        {
            _processID = pid;
            _handle = handle;
            this.owned = true;
        }
        this(int pid) @safe pure nothrow
        {
            _processID = pid;
            this.owned = false;
        }
    }
    else
    {
        this(int id, bool owned) @safe pure nothrow
        {
            _processID = id;
            this.owned = owned;
        }
    }
}


/**
Waits for the process associated with `pid` to terminate, and returns
its exit status.

In general one should always _wait for child processes to terminate
before exiting the parent process unless the process was spawned as detached
(that was spawned with `Config.detached` flag).
Otherwise, they may become "$(HTTP en.wikipedia.org/wiki/Zombie_process,zombies)"
– processes that are defunct, yet still occupy a slot in the OS process table.
You should not and must not wait for detached processes, since you don't own them.

If the process has already terminated, this function returns directly.
The exit code is cached, so that if wait() is called multiple times on
the same $(LREF Pid) it will always return the same value.

POSIX_specific:
If the process is terminated by a signal, this function returns a
negative number whose absolute value is the signal number.
Since POSIX restricts normal exit codes to the range 0-255, a
negative return value will always indicate termination by signal.
Signal codes are defined in the `core.sys.posix.signal` module
(which corresponds to the `signal.h` POSIX header).

Throws:
$(LREF ProcessException) on failure or on attempt to wait for detached process.

Example:
See the $(LREF spawnProcess) documentation.

See_also:
$(LREF tryWait), for a non-blocking function.
*/
int wait(Pid pid) @safe
{
    assert(pid !is null, "Called wait on a null Pid.");
    return pid.performWait(true);
}


@system unittest // Pid and wait()
{
    version (Windows)    TestScript prog = "exit %~1";
    else version (Posix) TestScript prog = "exit $1";
    assert(wait(spawnProcess([prog.path, "0"])) == 0);
    assert(wait(spawnProcess([prog.path, "123"])) == 123);
    auto pid = spawnProcess([prog.path, "10"]);
    assert(pid.processID > 0);
    version (Windows)    assert(pid.osHandle != INVALID_HANDLE_VALUE);
    else version (Posix) assert(pid.osHandle == pid.processID);
    assert(wait(pid) == 10);
    assert(wait(pid) == 10); // cached exit code
    assert(pid.processID < 0);
    version (Windows)    assert(pid.osHandle == INVALID_HANDLE_VALUE);
    else version (Posix) assert(pid.osHandle < 0);
}

private import std.typecons : Tuple;

/**
Waits until either the process associated with `pid` terminates or the
elapsed time exceeds the given timeout.

If the process terminates within the given duration it behaves exactly like
`wait`, except that it returns a tuple `(true, exit code)`.

If the process does not terminate within the given duration it will stop
waiting and return `(false, 0).`

The timeout may not exceed `(uint.max - 1).msecs` (~ 7 weeks, 17 hours).

$(BLUE This function is Windows-Only.)

Returns:
An $(D std.typecons.Tuple!(bool, "terminated", int, "status")).

Throws:
$(LREF ProcessException) on failure or on attempt to wait for detached process.

Example:
See the $(LREF spawnProcess) documentation.

See_also:
$(LREF wait), for a blocking function without timeout.
$(LREF tryWait), for a non-blocking function without timeout.
*/
version (StdDdoc)
Tuple!(bool, "terminated", int, "status") waitTimeout(Pid pid, Duration timeout) @safe;

else version (Windows)
Tuple!(bool, "terminated", int, "status") waitTimeout(Pid pid, Duration timeout) @safe
{
    assert(pid !is null, "Called wait on a null Pid.");
    auto code = pid.performWait(timeout);
    return typeof(return)(pid._processID == Pid.terminated, code);
}

version (Windows)
@system unittest // Pid and waitTimeout()
{
    import std.exception : collectException;
    import std.typecons : tuple;

    TestScript prog = ":Loop\r\n" ~ "goto Loop";
    auto pid = spawnProcess(prog.path);

    // Doesn't block longer than one second
    assert(waitTimeout(pid, 1.seconds) == tuple(false, 0));

    kill(pid);
    assert(waitTimeout(pid, 1.seconds) == tuple(true, 1)); // exit 1 because the process is killed

    // Rejects timeouts exceeding the Windows API capabilities
    const dur = DWORD.max.msecs;
    const ex = collectException!ProcessException(waitTimeout(pid, dur));
    assert(ex);
    assert(ex.msg == "Timeout exceeds maximum wait time!");
}

/**
A non-blocking version of $(LREF wait).

If the process associated with `pid` has already terminated,
`tryWait` has the exact same effect as `wait`.
In this case, it returns a tuple where the `terminated` field
is set to `true` and the `status` field has the same
interpretation as the return value of `wait`.

If the process has $(I not) yet terminated, this function differs
from `wait` in that does not wait for this to happen, but instead
returns immediately.  The `terminated` field of the returned
tuple will then be set to `false`, while the `status` field
will always be 0 (zero).  `wait` or `tryWait` should then be
called again on the same `Pid` at some later time; not only to
get the exit code, but also to avoid the process becoming a "zombie"
when it finally terminates.  (See $(LREF wait) for details).

Returns:
An $(D std.typecons.Tuple!(bool, "terminated", int, "status")).

Throws:
$(LREF ProcessException) on failure or on attempt to wait for detached process.

Example:
---
auto pid = spawnProcess("dmd myapp.d");
scope(exit) wait(pid);
...
auto dmd = tryWait(pid);
if (dmd.terminated)
{
    if (dmd.status == 0) writeln("Compilation succeeded!");
    else writeln("Compilation failed");
}
else writeln("Still compiling...");
...
---
Note that in this example, the first `wait` call will have no
effect if the process has already terminated by the time `tryWait`
is called.  In the opposite case, however, the `scope` statement
ensures that we always wait for the process if it hasn't terminated
by the time we reach the end of the scope.
*/
auto tryWait(Pid pid) @safe
{
    import std.typecons : Tuple;
    assert(pid !is null, "Called tryWait on a null Pid.");
    auto code = pid.performWait(false);
    return Tuple!(bool, "terminated", int, "status")(pid._processID == Pid.terminated, code);
}
// unittest: This function is tested together with kill() below.


/**
Attempts to terminate the process associated with `pid`.

The effect of this function, as well as the meaning of `codeOrSignal`,
is highly platform dependent.  Details are given below.  Common to all
platforms is that this function only $(I initiates) termination of the process,
and returns immediately.  It does not wait for the process to end,
nor does it guarantee that the process does in fact get terminated.

Always call $(LREF wait) to wait for a process to complete, even if `kill`
has been called on it.

Windows_specific:
The process will be
$(LINK2 http://msdn.microsoft.com/en-us/library/windows/desktop/ms686714%28v=vs.100%29.aspx,
forcefully and abruptly terminated).  If `codeOrSignal` is specified, it
must be a nonnegative number which will be used as the exit code of the process.
If not, the process wil exit with code 1.  Do not use $(D codeOrSignal = 259),
as this is a special value (aka. $(LINK2 http://msdn.microsoft.com/en-us/library/windows/desktop/ms683189.aspx,STILL_ACTIVE))
used by Windows to signal that a process has in fact $(I not) terminated yet.
---
auto pid = spawnProcess("some_app");
kill(pid, 10);
assert(wait(pid) == 10);
---

POSIX_specific:
A $(LINK2 http://en.wikipedia.org/wiki/Unix_signal,signal) will be sent to
the process, whose value is given by `codeOrSignal`.  Depending on the
signal sent, this may or may not terminate the process.  Symbolic constants
for various $(LINK2 http://en.wikipedia.org/wiki/Unix_signal#POSIX_signals,
POSIX signals) are defined in `core.sys.posix.signal`, which corresponds to the
$(LINK2 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html,
`signal.h` POSIX header).  If `codeOrSignal` is omitted, the
`SIGTERM` signal will be sent.  (This matches the behaviour of the
$(LINK2 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/kill.html,
`_kill`) shell command.)
---
import core.sys.posix.signal : SIGKILL;
auto pid = spawnProcess("some_app");
kill(pid, SIGKILL);
assert(wait(pid) == -SIGKILL); // Negative return value on POSIX!
---

Throws:
$(LREF ProcessException) on error (e.g. if codeOrSignal is invalid).
    or on attempt to kill detached process.
    Note that failure to terminate the process is considered a "normal"
    outcome, not an error.$(BR)
*/
void kill(Pid pid)
{
    version (Windows) kill(pid, 1);
    else version (Posix)
    {
        import core.sys.posix.signal : SIGTERM;
        kill(pid, SIGTERM);
    }
}

/// ditto
void kill(Pid pid, int codeOrSignal)
{
    import std.exception : enforce;
    enforce!ProcessException(pid.owned, "Can't kill detached process");
    version (Windows)
    {
        if (codeOrSignal < 0) throw new ProcessException("Invalid exit code");
        // On Windows, TerminateProcess() appears to terminate the
        // *current* process if it is passed an invalid handle...
        if (pid.osHandle == INVALID_HANDLE_VALUE)
            throw new ProcessException("Invalid process handle");
        if (!TerminateProcess(pid.osHandle, codeOrSignal))
            throw ProcessException.newFromLastError();
    }
    else version (Posix)
    {
        import core.sys.posix.signal : kill;
        if (kill(pid.osHandle, codeOrSignal) == -1)
            throw ProcessException.newFromErrno();
    }
}

@system unittest // tryWait() and kill()
{
    import core.thread;
    import std.exception : assertThrown;
    // The test script goes into an infinite loop.
    version (Windows)
    {
        TestScript prog = ":loop
                           goto loop";
    }
    else version (Posix)
    {
        import core.sys.posix.signal : SIGTERM, SIGKILL;
        TestScript prog = "while true; do sleep 1; done";
    }
    auto pid = spawnProcess(prog.path);
    // Android appears to automatically kill sleeping processes very quickly,
    // so shorten the wait before killing here.
    version (Android)
        Thread.sleep(dur!"msecs"(5));
    else
        Thread.sleep(dur!"msecs"(500));
    kill(pid);
    version (Windows)    assert(wait(pid) == 1);
    else version (Posix) assert(wait(pid) == -SIGTERM);

    pid = spawnProcess(prog.path);
    Thread.sleep(dur!"msecs"(500));
    auto s = tryWait(pid);
    assert(!s.terminated && s.status == 0);
    assertThrown!ProcessException(kill(pid, -123)); // Negative code not allowed.
    version (Windows)    kill(pid, 123);
    else version (Posix) kill(pid, SIGKILL);
    do { s = tryWait(pid); } while (!s.terminated);
    version (Windows)    assert(s.status == 123);
    else version (Posix) assert(s.status == -SIGKILL);
    assertThrown!ProcessException(kill(pid));
}

@system unittest // wait() and kill() detached process
{
    import core.thread;
    import std.exception : assertThrown;
    TestScript prog = "exit 0";
    auto pid = spawnProcess([prog.path], null, Config.detached);
    /*
    This sleep is needed because we can't wait() for detached process to end
    and therefore TestScript destructor may run at the same time as /bin/sh tries to start the script.
    This leads to the annoying message like "/bin/sh: 0: Can't open /tmp/std.process temporary file" to appear when running tests.
    It does not happen in unittests with non-detached processes because we always wait() for them to finish.
    */
    Thread.sleep(500.msecs);
    assert(!pid.owned);
    version (Windows) assert(pid.osHandle == INVALID_HANDLE_VALUE);
    assertThrown!ProcessException(wait(pid));
    assertThrown!ProcessException(kill(pid));
}


/**
Creates a unidirectional _pipe.

Data is written to one end of the _pipe and read from the other.
---
auto p = pipe();
p.writeEnd.writeln("Hello World");
p.writeEnd.flush();
assert(p.readEnd.readln().chomp() == "Hello World");
---
Pipes can, for example, be used for interprocess communication
by spawning a new process and passing one end of the _pipe to
the child, while the parent uses the other end.
(See also $(LREF pipeProcess) and $(LREF pipeShell) for an easier
way of doing this.)
---
// Use cURL to download the dlang.org front page, pipe its
// output to grep to extract a list of links to ZIP files,
// and write the list to the file "D downloads.txt":
auto p = pipe();
auto outFile = File("D downloads.txt", "w");
auto cpid = spawnProcess(["curl", "http://dlang.org/download.html"],
                         std.stdio.stdin, p.writeEnd);
scope(exit) wait(cpid);
auto gpid = spawnProcess(["grep", "-o", `http://\S*\.zip`],
                         p.readEnd, outFile);
scope(exit) wait(gpid);
---

Returns:
A $(LREF Pipe) object that corresponds to the created _pipe.

Throws:
$(REF StdioException, std,stdio) on failure.
*/
version (Posix)
Pipe pipe() @trusted //TODO: @safe
{
    import core.sys.posix.stdio : fdopen;
    int[2] fds;
    if (core.sys.posix.unistd.pipe(fds) != 0)
        throw new StdioException("Unable to create pipe");
    Pipe p;
    auto readFP = fdopen(fds[0], "r");
    if (readFP == null)
        throw new StdioException("Cannot open read end of pipe");
    p._read = File(readFP, null);
    auto writeFP = fdopen(fds[1], "w");
    if (writeFP == null)
        throw new StdioException("Cannot open write end of pipe");
    p._write = File(writeFP, null);
    return p;
}
else version (Windows)
Pipe pipe() @trusted //TODO: @safe
{
    // use CreatePipe to create an anonymous pipe
    HANDLE readHandle;
    HANDLE writeHandle;
    if (!CreatePipe(&readHandle, &writeHandle, null, 0))
    {
        throw new StdioException(
            "Error creating pipe (" ~ generateSysErrorMsg() ~ ')',
            0);
    }

    scope(failure)
    {
        CloseHandle(readHandle);
        CloseHandle(writeHandle);
    }

    try
    {
        Pipe p;
        p._read .windowsHandleOpen(readHandle , "r");
        p._write.windowsHandleOpen(writeHandle, "a");
        return p;
    }
    catch (Exception e)
    {
        throw new StdioException("Error attaching pipe (" ~ e.msg ~ ")",
            0);
    }
}


/// An interface to a pipe created by the $(LREF pipe) function.
struct Pipe
{
    /// The read end of the pipe.
    @property File readEnd() @safe nothrow { return _read; }


    /// The write end of the pipe.
    @property File writeEnd() @safe nothrow { return _write; }


    /**
    Closes both ends of the pipe.

    Normally it is not necessary to do this manually, as $(REF File, std,stdio)
    objects are automatically closed when there are no more references
    to them.

    Note that if either end of the pipe has been passed to a child process,
    it will only be closed in the parent process.  (What happens in the
    child process is platform dependent.)

    Throws:
    $(REF ErrnoException, std,exception) if an error occurs.
    */
    void close() @safe
    {
        _read.close();
        _write.close();
    }

private:
    File _read, _write;
}

@system unittest
{
    import std.string;
    auto p = pipe();
    p.writeEnd.writeln("Hello World");
    p.writeEnd.flush();
    assert(p.readEnd.readln().chomp() == "Hello World");
    p.close();
    assert(!p.readEnd.isOpen);
    assert(!p.writeEnd.isOpen);
}


/**
Starts a new process, creating pipes to redirect its standard
input, output and/or error streams.

`pipeProcess` and `pipeShell` are convenient wrappers around
$(LREF spawnProcess) and $(LREF spawnShell), respectively, and
automate the task of redirecting one or more of the child process'
standard streams through pipes.  Like the functions they wrap,
these functions return immediately, leaving the child process to
execute in parallel with the invoking process.  It is recommended
to always call $(LREF wait) on the returned $(LREF ProcessPipes.pid),
as detailed in the documentation for `wait`.

The `args`/`program`/`command`, `env` and `config`
parameters are forwarded straight to the underlying spawn functions,
and we refer to their documentation for details.

Params:
args      = An array which contains the program name as the zeroth element
            and any command-line arguments in the following elements.
            (See $(LREF spawnProcess) for details.)
program   = The program name, $(I without) command-line arguments.
            (See $(LREF spawnProcess) for details.)
command   = A shell command which is passed verbatim to the command
            interpreter.  (See $(LREF spawnShell) for details.)
redirect  = Flags that determine which streams are redirected, and
            how.  See $(LREF Redirect) for an overview of available
            flags.
env       = Additional environment variables for the child process.
            (See $(LREF spawnProcess) for details.)
config    = Flags that control process creation. See $(LREF Config)
            for an overview of available flags, and note that the
            `retainStd...` flags have no effect in this function.
workDir   = The working directory for the new process.
            By default the child process inherits the parent's working
            directory.
shellPath = The path to the shell to use to run the specified program.
            By default this is $(LREF nativeShell).

Returns:
A $(LREF ProcessPipes) object which contains $(REF File, std,stdio)
handles that communicate with the redirected streams of the child
process, along with a $(LREF Pid) object that corresponds to the
spawned process.

Throws:
$(LREF ProcessException) on failure to start the process.$(BR)
$(REF StdioException, std,stdio) on failure to redirect any of the streams.$(BR)

Example:
---
// my_application writes to stdout and might write to stderr
auto pipes = pipeProcess("my_application", Redirect.stdout | Redirect.stderr);
scope(exit) wait(pipes.pid);

// Store lines of output.
string[] output;
foreach (line; pipes.stdout.byLine) output ~= line.idup;

// Store lines of errors.
string[] errors;
foreach (line; pipes.stderr.byLine) errors ~= line.idup;


// sendmail expects to read from stdin
pipes = pipeProcess(["/usr/bin/sendmail", "-t"], Redirect.stdin);
pipes.stdin.writeln("To: you");
pipes.stdin.writeln("From: me");
pipes.stdin.writeln("Subject: dlang");
pipes.stdin.writeln("");
pipes.stdin.writeln(message);

// a single period tells sendmail we are finished
pipes.stdin.writeln(".");

// but at this point sendmail might not see it, we need to flush
pipes.stdin.flush();

// sendmail happens to exit on ".", but some you have to close the file:
pipes.stdin.close();

// otherwise this wait will wait forever
wait(pipes.pid);

---
*/
ProcessPipes pipeProcess(scope const(char[])[] args,
                         Redirect redirect = Redirect.all,
                         const string[string] env = null,
                         Config config = Config.none,
                         scope const(char)[] workDir = null)
    @safe
{
    return pipeProcessImpl!spawnProcess(args, redirect, env, config, workDir);
}

/// ditto
ProcessPipes pipeProcess(scope const(char)[] program,
                         Redirect redirect = Redirect.all,
                         const string[string] env = null,
                         Config config = Config.none,
                         scope const(char)[] workDir = null)
    @safe
{
    return pipeProcessImpl!spawnProcess(program, redirect, env, config, workDir);
}

/// ditto
ProcessPipes pipeShell(scope const(char)[] command,
                       Redirect redirect = Redirect.all,
                       const string[string] env = null,
                       Config config = Config.none,
                       scope const(char)[] workDir = null,
                       string shellPath = nativeShell)
    @safe
{
    return pipeProcessImpl!spawnShell(command,
                                      redirect,
                                      env,
                                      config,
                                      workDir,
                                      shellPath);
}

// Implementation of the pipeProcess() family of functions.
private ProcessPipes pipeProcessImpl(alias spawnFunc, Cmd, ExtraSpawnFuncArgs...)
                                    (scope Cmd command,
                                     Redirect redirectFlags,
                                     const string[string] env = null,
                                     Config config = Config.none,
                                     scope const(char)[] workDir = null,
                                     ExtraSpawnFuncArgs extraArgs = ExtraSpawnFuncArgs.init)
    @trusted //TODO: @safe
{
    File childStdin, childStdout, childStderr;
    ProcessPipes pipes;
    pipes._redirectFlags = redirectFlags;

    if (redirectFlags & Redirect.stdin)
    {
        auto p = pipe();
        childStdin = p.readEnd;
        pipes._stdin = p.writeEnd;
    }
    else
    {
        childStdin = std.stdio.stdin;
    }

    if (redirectFlags & Redirect.stdout)
    {
        if ((redirectFlags & Redirect.stdoutToStderr) != 0)
            throw new StdioException("Cannot create pipe for stdout AND "
                                     ~"redirect it to stderr", 0);
        auto p = pipe();
        childStdout = p.writeEnd;
        pipes._stdout = p.readEnd;
    }
    else
    {
        childStdout = std.stdio.stdout;
    }

    if (redirectFlags & Redirect.stderr)
    {
        if ((redirectFlags & Redirect.stderrToStdout) != 0)
            throw new StdioException("Cannot create pipe for stderr AND "
                                     ~"redirect it to stdout", 0);
        auto p = pipe();
        childStderr = p.writeEnd;
        pipes._stderr = p.readEnd;
    }
    else
    {
        childStderr = std.stdio.stderr;
    }

    if (redirectFlags & Redirect.stdoutToStderr)
    {
        if (redirectFlags & Redirect.stderrToStdout)
        {
            // We know that neither of the other options have been
            // set, so we assign the std.stdio.std* streams directly.
            childStdout = std.stdio.stderr;
            childStderr = std.stdio.stdout;
        }
        else
        {
            childStdout = childStderr;
        }
    }
    else if (redirectFlags & Redirect.stderrToStdout)
    {
        childStderr = childStdout;
    }

    config.flags &= ~(Config.Flags.retainStdin | Config.Flags.retainStdout | Config.Flags.retainStderr);
    pipes._pid = spawnFunc(command, childStdin, childStdout, childStderr,
                           env, config, workDir, extraArgs);
    return pipes;
}


/**
Flags that can be passed to $(LREF pipeProcess) and $(LREF pipeShell)
to specify which of the child process' standard streams are redirected.
Use bitwise OR to combine flags.
*/
enum Redirect
{
    /// Redirect the standard input, output or error streams, respectively.
    stdin = 1,
    stdout = 2,                             /// ditto
    stderr = 4,                             /// ditto

    /**
    Redirect _all three streams.  This is equivalent to
    $(D Redirect.stdin | Redirect.stdout | Redirect.stderr).
    */
    all = stdin | stdout | stderr,

    /**
    Redirect the standard error stream into the standard output stream.
    This can not be combined with `Redirect.stderr`.
    */
    stderrToStdout = 8,

    /**
    Redirect the standard output stream into the standard error stream.
    This can not be combined with `Redirect.stdout`.
    */
    stdoutToStderr = 16,
}

@system unittest
{
    import std.string;
    version (Windows) TestScript prog =
       "call :sub %~1 %~2 0
        call :sub %~1 %~2 1
        call :sub %~1 %~2 2
        call :sub %~1 %~2 3
        exit 3

        :sub
        set /p INPUT=
        if -%INPUT%-==-stop- ( exit %~3 )
        echo %INPUT% %~1
        echo %INPUT% %~2 1>&2";
    else version (Posix) TestScript prog =
       `for EXITCODE in 0 1 2 3; do
            read INPUT
            if test "$INPUT" = stop; then break; fi
            echo "$INPUT $1"
            echo "$INPUT $2" >&2
        done
        exit $EXITCODE`;
    auto pp = pipeProcess([prog.path, "bar", "baz"]);
    pp.stdin.writeln("foo");
    pp.stdin.flush();
    assert(pp.stdout.readln().chomp() == "foo bar");
    assert(pp.stderr.readln().chomp().stripRight() == "foo baz");
    pp.stdin.writeln("1234567890");
    pp.stdin.flush();
    assert(pp.stdout.readln().chomp() == "1234567890 bar");
    assert(pp.stderr.readln().chomp().stripRight() == "1234567890 baz");
    pp.stdin.writeln("stop");
    pp.stdin.flush();
    assert(wait(pp.pid) == 2);

    pp = pipeProcess([prog.path, "12345", "67890"],
                     Redirect.stdin | Redirect.stdout | Redirect.stderrToStdout);
    pp.stdin.writeln("xyz");
    pp.stdin.flush();
    assert(pp.stdout.readln().chomp() == "xyz 12345");
    assert(pp.stdout.readln().chomp().stripRight() == "xyz 67890");
    pp.stdin.writeln("stop");
    pp.stdin.flush();
    assert(wait(pp.pid) == 1);

    pp = pipeShell(escapeShellCommand(prog.path, "AAAAA", "BBB"),
                   Redirect.stdin | Redirect.stdoutToStderr | Redirect.stderr);
    pp.stdin.writeln("ab");
    pp.stdin.flush();
    assert(pp.stderr.readln().chomp() == "ab AAAAA");
    assert(pp.stderr.readln().chomp().stripRight() == "ab BBB");
    pp.stdin.writeln("stop");
    pp.stdin.flush();
    assert(wait(pp.pid) == 1);
}

@system unittest
{
    import std.exception : assertThrown;
    TestScript prog = "exit 0";
    assertThrown!StdioException(pipeProcess(
        prog.path,
        Redirect.stdout | Redirect.stdoutToStderr));
    assertThrown!StdioException(pipeProcess(
        prog.path,
        Redirect.stderr | Redirect.stderrToStdout));
    auto p = pipeProcess(prog.path, Redirect.stdin);
    assertThrown!Error(p.stdout);
    assertThrown!Error(p.stderr);
    wait(p.pid);
    p = pipeProcess(prog.path, Redirect.stderr);
    assertThrown!Error(p.stdin);
    assertThrown!Error(p.stdout);
    wait(p.pid);
}

/**
Object which contains $(REF File, std,stdio) handles that allow communication
with a child process through its standard streams.
*/
struct ProcessPipes
{
    /// The $(LREF Pid) of the child process.
    @property Pid pid() @safe nothrow
    {
        return _pid;
    }

    /**
    An $(REF File, std,stdio) that allows writing to the child process'
    standard input stream.

    Throws:
    $(OBJECTREF Error) if the child process' standard input stream hasn't
    been redirected.
    */
    @property File stdin() @safe nothrow
    {
        if ((_redirectFlags & Redirect.stdin) == 0)
            throw new Error("Child process' standard input stream hasn't "
                            ~"been redirected.");
        return _stdin;
    }

    /**
    An $(REF File, std,stdio) that allows reading from the child process'
    standard output stream.

    Throws:
    $(OBJECTREF Error) if the child process' standard output stream hasn't
    been redirected.
    */
    @property File stdout() @safe nothrow
    {
        if ((_redirectFlags & Redirect.stdout) == 0)
            throw new Error("Child process' standard output stream hasn't "
                            ~"been redirected.");
        return _stdout;
    }

    /**
    An $(REF File, std,stdio) that allows reading from the child process'
    standard error stream.

    Throws:
    $(OBJECTREF Error) if the child process' standard error stream hasn't
    been redirected.
    */
    @property File stderr() @safe nothrow
    {
        if ((_redirectFlags & Redirect.stderr) == 0)
            throw new Error("Child process' standard error stream hasn't "
                            ~"been redirected.");
        return _stderr;
    }

private:
    Redirect _redirectFlags;
    Pid _pid;
    File _stdin, _stdout, _stderr;
}



/**
Executes the given program or shell command and returns its exit
code and output.

`execute` and `executeShell` start a new process using
$(LREF spawnProcess) and $(LREF spawnShell), respectively, and wait
for the process to complete before returning.  The functions capture
what the child process prints to both its standard output and
standard error streams, and return this together with its exit code.
---
auto dmd = execute(["dmd", "myapp.d"]);
if (dmd.status != 0) writeln("Compilation failed:\n", dmd.output);

auto ls = executeShell("ls -l");
if (ls.status != 0) writeln("Failed to retrieve file listing");
else writeln(ls.output);
---

The `args`/`program`/`command`, `env` and `config`
parameters are forwarded straight to the underlying spawn functions,
and we refer to their documentation for details.

Params:
args      = An array which contains the program name as the zeroth element
            and any command-line arguments in the following elements.
            (See $(LREF spawnProcess) for details.)
program   = The program name, $(I without) command-line arguments.
            (See $(LREF spawnProcess) for details.)
command   = A shell command which is passed verbatim to the command
            interpreter.  (See $(LREF spawnShell) for details.)
env       = Additional environment variables for the child process.
            (See $(LREF spawnProcess) for details.)
config    = Flags that control process creation. See $(LREF Config)
            for an overview of available flags, and note that the
            `retainStd...` flags have no effect in this function.
maxOutput = The maximum number of bytes of output that should be
            captured.
workDir   = The working directory for the new process.
            By default the child process inherits the parent's working
            directory.
shellPath = The path to the shell to use to run the specified program.
            By default this is $(LREF nativeShell).


Returns:
An $(D std.typecons.Tuple!(int, "status", string, "output")).

POSIX_specific:
If the process is terminated by a signal, the `status` field of
the return value will contain a negative number whose absolute
value is the signal number.  (See $(LREF wait) for details.)

Throws:
$(LREF ProcessException) on failure to start the process.$(BR)
$(REF StdioException, std,stdio) on failure to capture output.
*/
auto execute(scope const(char[])[] args,
             const string[string] env = null,
             Config config = Config.none,
             size_t maxOutput = size_t.max,
             scope const(char)[] workDir = null)
    @safe
{
    return executeImpl!pipeProcess(args, env, config, maxOutput, workDir);
}

/// ditto
auto execute(scope const(char)[] program,
             const string[string] env = null,
             Config config = Config.none,
             size_t maxOutput = size_t.max,
             scope const(char)[] workDir = null)
    @safe
{
    return executeImpl!pipeProcess(program, env, config, maxOutput, workDir);
}

/// ditto
auto executeShell(scope const(char)[] command,
                  const string[string] env = null,
                  Config config = Config.none,
                  size_t maxOutput = size_t.max,
                  scope const(char)[] workDir = null,
                  string shellPath = nativeShell)
    @safe
{
    return executeImpl!pipeShell(command,
                                 env,
                                 config,
                                 maxOutput,
                                 workDir,
                                 shellPath);
}

// Does the actual work for execute() and executeShell().
private auto executeImpl(alias pipeFunc, Cmd, ExtraPipeFuncArgs...)(
    Cmd commandLine,
    const string[string] env = null,
    Config config = Config.none,
    size_t maxOutput = size_t.max,
    scope const(char)[] workDir = null,
    ExtraPipeFuncArgs extraArgs = ExtraPipeFuncArgs.init)
    @trusted //TODO: @safe
{
    import std.algorithm.comparison : min;
    import std.array : appender;
    import std.typecons : Tuple;

    auto redirect = (config.flags & Config.Flags.stderrPassThrough)
        ? Redirect.stdout
        : Redirect.stdout | Redirect.stderrToStdout;

    auto p = pipeFunc(commandLine, redirect,
                      env, config, workDir, extraArgs);

    auto a = appender!string;
    enum size_t defaultChunkSize = 4096;
    immutable chunkSize = min(maxOutput, defaultChunkSize);

    // Store up to maxOutput bytes in a.
    foreach (ubyte[] chunk; p.stdout.byChunk(chunkSize))
    {
        immutable size_t remain = maxOutput - a.data.length;

        if (chunk.length < remain) a.put(chunk);
        else
        {
            a.put(chunk[0 .. remain]);
            break;
        }
    }
    // Exhaust the stream, if necessary.
    foreach (ubyte[] chunk; p.stdout.byChunk(defaultChunkSize)) { }

    return Tuple!(int, "status", string, "output")(wait(p.pid), a.data);
}

@system unittest
{
    import std.string;
    // To avoid printing the newline characters, we use the echo|set trick on
    // Windows, and printf on POSIX (neither echo -n nor echo \c are portable).
    version (Windows) TestScript prog =
       "echo|set /p=%~1
        echo|set /p=%~2 1>&2
        exit 123";
    else version (Android) TestScript prog =
       `echo -n $1
        echo -n $2 >&2
        exit 123`;
    else version (Posix) TestScript prog =
       `printf '%s' $1
        printf '%s' $2 >&2
        exit 123`;
    auto r = execute([prog.path, "foo", "bar"]);
    assert(r.status == 123);
    assert(r.output.stripRight() == "foobar");
    auto s = execute([prog.path, "Hello", "World"]);
    assert(s.status == 123);
    assert(s.output.stripRight() == "HelloWorld");
}

@safe unittest
{
    import std.string;
    auto r1 = executeShell("echo foo");
    assert(r1.status == 0);
    assert(r1.output.chomp() == "foo");
    auto r2 = executeShell("echo bar 1>&2");
    assert(r2.status == 0);
    assert(r2.output.chomp().stripRight() == "bar");
    auto r3 = executeShell("exit 123");
    assert(r3.status == 123);
    assert(r3.output.empty);
}

@system unittest
{
    // Temporarily disable output to stderr so as to not spam the build log.
    import std.stdio : stderr;
    import std.typecons : Tuple;
    import std.file : readText, exists, remove;
    import std.traits : ReturnType;

    ReturnType!executeShell r;
    auto tmpname = uniqueTempPath;
    scope(exit) if (exists(tmpname)) remove(tmpname);
    auto t = stderr;
    // Open a new scope to minimize code ran with stderr redirected.
    {
        stderr.open(tmpname, "w");
        scope(exit) stderr = t;
        r = executeShell("echo D rox>&2", null, Config.stderrPassThrough);
    }
    assert(r.status == 0);
    assert(r.output.empty);
    auto witness = readText(tmpname);
    import std.ascii : newline;
    assert(witness == "D rox" ~ newline, "'" ~ witness ~ "'");
}

@safe unittest
{
    import std.typecons : Tuple;
    void foo() //Just test the compilation
    {
        auto ret1 = execute(["dummy", "arg"]);
        auto ret2 = executeShell("dummy arg");
        static assert(is(typeof(ret1) == typeof(ret2)));

        Tuple!(int, string) ret3 = execute(["dummy", "arg"]);
    }
}

/// An exception that signals a problem with starting or waiting for a process.
class ProcessException : Exception
{
    import std.exception : basicExceptionCtors;
    mixin basicExceptionCtors;

    // Creates a new ProcessException based on errno.
    static ProcessException newFromErrno(string customMsg = null,
                                         string file = __FILE__,
                                         size_t line = __LINE__)
    {
        import core.stdc.errno : errno;
        return newFromErrno(errno, customMsg, file, line);
    }

    // ditto, but error number is provided by caller
    static ProcessException newFromErrno(int error,
                                         string customMsg = null,
                                         string file = __FILE__,
                                         size_t line = __LINE__)
    {
        import std.exception : errnoString;
        auto errnoMsg = errnoString(error);
        auto msg = customMsg.empty ? errnoMsg
                                   : customMsg ~ " (" ~ errnoMsg ~ ')';
        return new ProcessException(msg, file, line);
    }

    // Creates a new ProcessException based on GetLastError() (Windows only).
    version (Windows)
    static ProcessException newFromLastError(string customMsg = null,
                                             string file = __FILE__,
                                             size_t line = __LINE__)
    {
        auto lastMsg = generateSysErrorMsg();
        auto msg = customMsg.empty ? lastMsg
                                   : customMsg ~ " (" ~ lastMsg ~ ')';
        return new ProcessException(msg, file, line);
    }
}


/**
Determines the path to the current user's preferred command interpreter.

On Windows, this function returns the contents of the COMSPEC environment
variable, if it exists.  Otherwise, it returns the result of $(LREF nativeShell).

On POSIX, `userShell` returns the contents of the SHELL environment
variable, if it exists and is non-empty.  Otherwise, it returns the result of
$(LREF nativeShell).
*/
@property string userShell() @safe
{
    version (Windows)      return environment.get("COMSPEC", nativeShell);
    else version (Posix)   return environment.get("SHELL", nativeShell);
}

/**
The platform-specific native shell path.

This function returns `"cmd.exe"` on Windows, `"/bin/sh"` on POSIX, and
`"/system/bin/sh"` on Android.
*/
@property string nativeShell() @safe @nogc pure nothrow
{
    version (Windows)      return "cmd.exe";
    else version (Android) return "/system/bin/sh";
    else version (Posix)   return "/bin/sh";
}

// A command-line switch that indicates to the shell that it should
// interpret the following argument as a command to be executed.
version (Posix)   private immutable string shellSwitch = "-c";
version (Windows) private immutable string shellSwitch = "/C";

// Unittest support code:  TestScript takes a string that contains a
// shell script for the current platform, and writes it to a temporary
// file. On Windows the file name gets a .cmd extension, while on
// POSIX its executable permission bit is set.  The file is
// automatically deleted when the object goes out of scope.
version (StdUnittest)
private struct TestScript
{
    this(string code) @system
    {
        // @system due to chmod
        import std.ascii : newline;
        import std.file : write;
        version (Windows)
        {
            auto ext = ".cmd";
            auto firstLine = "@echo off";
        }
        else version (Posix)
        {
            auto ext = "";
            auto firstLine = "#!" ~ nativeShell;
        }
        path = uniqueTempPath()~ext;
        write(path, firstLine ~ newline ~ code ~ newline);
        version (Posix)
        {
            import core.sys.posix.sys.stat : chmod;
            import std.conv : octal;
            chmod(path.tempCString(), octal!777);
        }
    }

    ~this()
    {
        import std.file : remove, exists;
        if (!path.empty && exists(path))
        {
            try { remove(path); }
            catch (Exception e)
            {
                debug std.stdio.stderr.writeln(e.msg);
            }
        }
    }

    string path;
}


// =============================================================================
// Functions for shell command quoting/escaping.
// =============================================================================


/*
    Command line arguments exist in three forms:
    1) string or char* array, as received by main.
       Also used internally on POSIX systems.
    2) Command line string, as used in Windows'
       CreateProcess and CommandLineToArgvW functions.
       A specific quoting and escaping algorithm is used
       to distinguish individual arguments.
    3) Shell command string, as written at a shell prompt
       or passed to cmd /C - this one may contain shell
       control characters, e.g. > or | for redirection /
       piping - thus, yet another layer of escaping is
       used to distinguish them from program arguments.

    Except for escapeWindowsArgument, the intermediary
    format (2) is hidden away from the user in this module.
*/

/**
Escapes an argv-style argument array to be used with $(LREF spawnShell),
$(LREF pipeShell) or $(LREF executeShell).
---
string url = "http://dlang.org/";
executeShell(escapeShellCommand("wget", url, "-O", "dlang-index.html"));
---

Concatenate multiple `escapeShellCommand` and
$(LREF escapeShellFileName) results to use shell redirection or
piping operators.
---
executeShell(
    escapeShellCommand("curl", "http://dlang.org/download.html") ~
    "|" ~
    escapeShellCommand("grep", "-o", `http://\S*\.zip`) ~
    ">" ~
    escapeShellFileName("D download links.txt"));
---

Throws:
$(OBJECTREF Exception) if any part of the command line contains unescapable
characters (NUL on all platforms, as well as CR and LF on Windows).
*/
string escapeShellCommand(scope const(char[])[] args...) @safe pure
{
    if (args.empty)
        return null;
    version (Windows)
    {
        // Do not ^-escape the first argument (the program path),
        // as the shell parses it differently from parameters.
        // ^-escaping a program path that contains spaces will fail.
        string result = escapeShellFileName(args[0]);
        if (args.length > 1)
        {
            result ~= " " ~ escapeShellCommandString(
                escapeShellArguments(args[1..$]));
        }
        return result;
    }
    version (Posix)
    {
        return escapeShellCommandString(escapeShellArguments(args));
    }
}

@safe unittest
{
    // This is a simple unit test without any special requirements,
    // in addition to the unittest_burnin one below which requires
    // special preparation.

    struct TestVector { string[] args; string windows, posix; }
    TestVector[] tests =
    [
        {
            args    : ["foo bar"],
            windows : `"foo bar"`,
            posix   : `'foo bar'`
        },
        {
            args    : ["foo bar", "hello"],
            windows : `"foo bar" hello`,
            posix   : `'foo bar' hello`
        },
        {
            args    : ["foo bar", "hello world"],
            windows : `"foo bar" ^"hello world^"`,
            posix   : `'foo bar' 'hello world'`
        },
        {
            args    : ["foo bar", "hello", "world"],
            windows : `"foo bar" hello world`,
            posix   : `'foo bar' hello world`
        },
        {
            args    : ["foo bar", `'"^\`],
            windows : `"foo bar" ^"'\^"^^\\^"`,
            posix   : `'foo bar' ''\''"^\'`
        },
        {
            args    : ["foo bar", ""],
            windows : `"foo bar" ^"^"`,
            posix   : `'foo bar' ''`
        },
        {
            args    : ["foo bar", "2"],
            windows : `"foo bar" ^"2^"`,
            posix   : `'foo bar' '2'`
        },
    ];

    foreach (test; tests)
    {
        auto actual = escapeShellCommand(test.args);
        version (Windows)
            string expected = test.windows;
        else
            string expected = test.posix;
        assert(actual == expected, "\nExpected: " ~ expected ~ "\nGot: " ~ actual);
    }
}

private string escapeShellCommandString(return scope string command) @safe pure
{
    version (Windows)
        return escapeWindowsShellCommand(command);
    else
        return command;
}

private string escapeWindowsShellCommand(scope const(char)[] command) @safe pure
{
    import std.array : appender;
    auto result = appender!string();
    result.reserve(command.length);

    foreach (c; command)
        switch (c)
        {
            case '\0':
                throw new Exception("Cannot put NUL in command line");
            case '\r':
            case '\n':
                throw new Exception("CR/LF are not escapable");
            case '\x01': .. case '\x09':
            case '\x0B': .. case '\x0C':
            case '\x0E': .. case '\x1F':
            case '"':
            case '^':
            case '&':
            case '<':
            case '>':
            case '|':
                result.put('^');
                goto default;
            default:
                result.put(c);
        }
    return result.data;
}

private string escapeShellArguments(scope const(char[])[] args...)
    @trusted pure nothrow
{
    import std.exception : assumeUnique;
    char[] buf;

    @safe nothrow
    char[] allocator(size_t size)
    {
        if (buf.length == 0)
            return buf = new char[size];
        else
        {
            auto p = buf.length;
            buf.length = buf.length + 1 + size;
            buf[p++] = ' ';
            return buf[p .. p+size];
        }
    }

    foreach (arg; args)
        escapeShellArgument!allocator(arg);
    return assumeUnique(buf);
}

private auto escapeShellArgument(alias allocator)(scope const(char)[] arg) @safe nothrow
{
    // The unittest for this function requires special
    // preparation - see below.

    version (Windows)
        return escapeWindowsArgumentImpl!allocator(arg);
    else
        return escapePosixArgumentImpl!allocator(arg);
}

/**
Quotes a command-line argument in a manner conforming to the behavior of
$(LINK2 http://msdn.microsoft.com/en-us/library/windows/desktop/bb776391(v=vs.85).aspx,
CommandLineToArgvW).
*/
string escapeWindowsArgument(scope const(char)[] arg) @trusted pure nothrow
{
    // Rationale for leaving this function as public:
    // this algorithm of escaping paths is also used in other software,
    // e.g. DMD's response files.
    import std.exception : assumeUnique;
    auto buf = escapeWindowsArgumentImpl!charAllocator(arg);
    return assumeUnique(buf);
}


private char[] charAllocator(size_t size) @safe pure nothrow
{
    return new char[size];
}


private char[] escapeWindowsArgumentImpl(alias allocator)(scope const(char)[] arg)
    @safe nothrow
if (is(typeof(allocator(size_t.init)[0] = char.init)))
{
    // References:
    // * http://msdn.microsoft.com/en-us/library/windows/desktop/bb776391(v=vs.85).aspx
    // * http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx

    // Check if the string needs to be escaped,
    // and calculate the total string size.

    // Trailing backslashes must be escaped
    bool escaping = true;
    bool needEscape = false;
    // Result size = input size + 2 for surrounding quotes + 1 for the
    // backslash for each escaped character.
    size_t size = 1 + arg.length + 1;

    foreach_reverse (char c; arg)
    {
        if (c == '"')
        {
            needEscape = true;
            escaping = true;
            size++;
        }
        else
        if (c == '\\')
        {
            if (escaping)
                size++;
        }
        else
        {
            if (c == ' ' || c == '\t')
                needEscape = true;
            escaping = false;
        }
    }

    import std.ascii : isDigit;
    // Empty arguments need to be specified as ""
    if (!arg.length)
        needEscape = true;
    else
    // Arguments ending with digits need to be escaped,
    // to disambiguate with 1>file redirection syntax
    if (isDigit(arg[$-1]))
        needEscape = true;

    if (!needEscape)
        return allocator(arg.length)[] = arg;

    // Construct result string.

    auto buf = allocator(size);
    size_t p = size;
    buf[--p] = '"';
    escaping = true;
    foreach_reverse (char c; arg)
    {
        if (c == '"')
            escaping = true;
        else
        if (c != '\\')
            escaping = false;

        buf[--p] = c;
        if (escaping)
            buf[--p] = '\\';
    }
    buf[--p] = '"';
    assert(p == 0);

    return buf;
}

version (Windows) version (StdUnittest)
{
private:
    import core.stdc.stddef;
    import core.stdc.wchar_ : wcslen;
    import core.sys.windows.shellapi : CommandLineToArgvW;
    import core.sys.windows.winbase;
    import core.sys.windows.winnt;
    import std.array;

    string[] parseCommandLine(string line)
    {
        import std.algorithm.iteration : map;
        import std.array : array;
        import std.conv : to;
        auto lpCommandLine = (to!(WCHAR[])(line) ~ '\0').ptr;
        int numArgs;
        auto args = CommandLineToArgvW(lpCommandLine, &numArgs);
        scope(exit) LocalFree(args);
        return args[0 .. numArgs]
            .map!(arg => to!string(arg[0 .. wcslen(arg)]))
            .array();
    }

    @system unittest
    {
        import std.conv : text;
        string[] testStrings = [
            `Hello`,
            `Hello, world`,
            `Hello, "world"`,
            `C:\`,
            `C:\dmd`,
            `C:\Program Files\`,
        ];

        enum CHARS = `_x\" *&^` ~ "\t"; // _ is placeholder for nothing
        foreach (c1; CHARS)
        foreach (c2; CHARS)
        foreach (c3; CHARS)
        foreach (c4; CHARS)
            testStrings ~= [c1, c2, c3, c4].replace("_", "");

        foreach (s; testStrings)
        {
            auto q = escapeWindowsArgument(s);
            auto args = parseCommandLine("Dummy.exe " ~ q);
            assert(args.length == 2, s ~ " => " ~ q ~ " #" ~ text(args.length-1));
            assert(args[1] == s, s ~ " => " ~ q ~ " => " ~ args[1]);
        }
    }
}

private string escapePosixArgument(scope const(char)[] arg) @trusted pure nothrow
{
    import std.exception : assumeUnique;
    auto buf = escapePosixArgumentImpl!charAllocator(arg);
    return assumeUnique(buf);
}

private char[] escapePosixArgumentImpl(alias allocator)(scope const(char)[] arg)
    @safe nothrow
if (is(typeof(allocator(size_t.init)[0] = char.init)))
{
    bool needQuoting = {
        import std.ascii : isAlphaNum, isDigit;
        import std.algorithm.comparison : among;

        // Empty arguments need to be specified as ''
        if (arg.length == 0)
            return true;
        // Arguments ending with digits need to be escaped,
        // to disambiguate with 1>file redirection syntax
        if (isDigit(arg[$-1]))
            return true;

        // Obtained using:
        // for n in $(seq 1 255) ; do
        //     c=$(printf \\$(printf "%o" $n))
        //     q=$(/bin/printf '%q' "$c")
        //     if [[ "$q" == "$c" ]] ; then printf "%s, " "'$c'" ; fi
        // done
        // printf '\n'
        foreach (char c; arg)
            if (!isAlphaNum(c) && !c.among('%', '+', ',', '-', '.', '/', ':', '@', ']', '_'))
                return true;
        return false;
    }();
    if (!needQuoting)
    {
        auto buf = allocator(arg.length);
        buf[] = arg;
        return buf;
    }

    // '\'' means: close quoted part of argument, append an escaped
    // single quote, and reopen quotes

    // Below code is equivalent to:
    // return `'` ~ std.array.replace(arg, `'`, `'\''`) ~ `'`;

    size_t size = 1 + arg.length + 1;
    foreach (char c; arg)
        if (c == '\'')
            size += 3;

    auto buf = allocator(size);
    size_t p = 0;
    buf[p++] = '\'';
    foreach (char c; arg)
        if (c == '\'')
        {
            buf[p .. p+4] = `'\''`;
            p += 4;
        }
        else
            buf[p++] = c;
    buf[p++] = '\'';
    assert(p == size);

    return buf;
}

/**
Escapes a filename to be used for shell redirection with $(LREF spawnShell),
$(LREF pipeShell) or $(LREF executeShell).
*/
string escapeShellFileName(scope const(char)[] fileName) @trusted pure nothrow
{
    // The unittest for this function requires special
    // preparation - see below.

    version (Windows)
    {
        // If a file starts with &, it can cause cmd.exe to misinterpret
        // the file name as the stream redirection syntax:
        //     command > "&foo.txt"
        // gets interpreted as
        //     command >&foo.txt
        // Prepend .\ to disambiguate.

        if (fileName.length && fileName[0] == '&')
            return cast(string)(`".\` ~ fileName ~ '"');

        return cast(string)('"' ~ fileName ~ '"');
    }
    else
        return escapePosixArgument(fileName);
}

// Loop generating strings with random characters
//version = unittest_burnin;

version (unittest_burnin)
@system unittest
{
    // There are no readily-available commands on all platforms suitable
    // for properly testing command escaping. The behavior of CMD's "echo"
    // built-in differs from the POSIX program, and Windows ports of POSIX
    // environments (Cygwin, msys, gnuwin32) may interfere with their own
    // "echo" ports.

    // To run this unit test, create std_process_unittest_helper.d with the
    // following content and compile it:
    // import std.stdio, std.array; void main(string[] args) { write(args.join("\0")); }
    // Then, test this module with:
    // rdmd --main -unittest -version=unittest_burnin process.d

    import std.file : readText, remove;
    import std.format : format;
    import std.path : absolutePath;
    import std.random : uniform;

    auto helper = absolutePath("std_process_unittest_helper");
    assert(executeShell(helper ~ " hello").output.split("\0")[1..$] == ["hello"], "Helper malfunction");

    void test(string[] s, string fn)
    {
        string e;
        string[] g;

        e = escapeShellCommand(helper ~ s);
        {
            scope(failure) writefln("executeShell() failed.\nExpected:\t%s\nEncoded:\t%s", s, [e]);
            auto result = executeShell(e);
            assert(result.status == 0, "std_process_unittest_helper failed");
            g = result.output.split("\0")[1..$];
        }
        assert(s == g, format("executeShell() test failed.\nExpected:\t%s\nGot:\t\t%s\nEncoded:\t%s", s, g, [e]));

        e = escapeShellCommand(helper ~ s) ~ ">" ~ escapeShellFileName(fn);
        {
            scope(failure) writefln(
                "executeShell() with redirect failed.\nExpected:\t%s\nFilename:\t%s\nEncoded:\t%s", s, [fn], [e]);
            auto result = executeShell(e);
            assert(result.status == 0, "std_process_unittest_helper failed");
            assert(!result.output.length, "No output expected, got:\n" ~ result.output);
            g = readText(fn).split("\0")[1..$];
        }
        remove(fn);
        assert(s == g,
            format("executeShell() with redirect test failed.\nExpected:\t%s\nGot:\t\t%s\nEncoded:\t%s", s, g, [e]));
    }

    while (true)
    {
        string[] args;
        foreach (n; 0 .. uniform(1, 4))
        {
            string arg;
            foreach (l; 0 .. uniform(0, 10))
            {
                dchar c;
                while (true)
                {
                    version (Windows)
                    {
                        // As long as DMD's system() uses CreateProcessA,
                        // we can't reliably pass Unicode
                        c = uniform(0, 128);
                    }
                    else
                        c = uniform!ubyte();

                    if (c == 0)
                        continue; // argv-strings are zero-terminated
                    version (Windows)
                        if (c == '\r' || c == '\n')
                            continue; // newlines are unescapable on Windows
                    break;
                }
                arg ~= c;
            }
            args ~= arg;
        }

        // generate filename
        string fn;
        foreach (l; 0 .. uniform(1, 10))
        {
            dchar c;
            while (true)
            {
                version (Windows)
                    c = uniform(0, 128); // as above
                else
                    c = uniform!ubyte();

                if (c == 0 || c == '/')
                    continue; // NUL and / are the only characters
                              // forbidden in POSIX filenames
                version (Windows)
                    if (c < '\x20' || c == '<' || c == '>' || c == ':' ||
                        c == '"' || c == '\\' || c == '|' || c == '?' || c == '*')
                        continue; // http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx
                break;
            }

            fn ~= c;
        }
        fn = fn[0..$/2] ~ "_testfile_" ~ fn[$/2..$];

        test(args, fn);
    }
}

// =============================================================================
// Everything below this line was part of the old std.process, and most of
// it will be deprecated and removed.
// =============================================================================


/*
Copyright: Copyright The D Language Foundation 2007 - 2009.
License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
Authors:   $(HTTP digitalmars.com, Walter Bright),
           $(HTTP erdani.org, Andrei Alexandrescu),
           $(HTTP thecybershadow.net, Vladimir Panteleev)
Source:    $(PHOBOSSRC std/_process.d)
*/
/*
         Copyright The D Language Foundation 2007 - 2009.
Distributed under the Boost Software License, Version 1.0.
   (See accompanying file LICENSE_1_0.txt or copy at
         http://www.boost.org/LICENSE_1_0.txt)
*/


import core.stdc.errno;
import core.stdc.stdlib;
import core.stdc.string;
import core.thread;

version (Windows)
{
    import std.file, std.format, std.random;
}
version (Posix)
{
    import core.sys.posix.stdlib;
}

private void toAStringz(in string[] a, const(char)**az)
{
    import std.string : toStringz;
    foreach (string s; a)
    {
        *az++ = toStringz(s);
    }
    *az = null;
}


/* ========================================================== */

//version (Windows)
//{
//    int spawnvp(int mode, string pathname, string[] argv)
//    {
//      char** argv_ = cast(char**) core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
//      scope(exit) core.stdc.stdlib.free(argv_);
//
//      toAStringz(argv, argv_);
//
//      return spawnvp(mode, pathname.tempCString(), argv_);
//    }
//}

// Incorporating idea (for spawnvp() on Posix) from Dave Fladebo

enum { _P_WAIT, _P_NOWAIT, _P_OVERLAY }
version (Windows) extern(C) int spawnvp(int, scope const(char) *, scope const(char*)*);
alias P_WAIT = _P_WAIT;
alias P_NOWAIT = _P_NOWAIT;

/* ========================================================== */

version (StdDdoc)
{
    /**
    Replaces the current process by executing a command, `pathname`, with
    the arguments in `argv`.

    $(BLUE This function is Posix-Only.)

    Typically, the first element of `argv` is
    the command being executed, i.e. $(D argv[0] == pathname). The 'p'
    versions of `exec` search the PATH environment variable for $(D
    pathname). The 'e' versions additionally take the new process'
    environment variables as an array of strings of the form key=value.

    Does not return on success (the current process will have been
    replaced). Returns -1 on failure with no indication of the
    underlying error.

    Windows_specific:
    These functions are only supported on POSIX platforms, as the Windows
    operating systems do not provide the ability to overwrite the current
    process image with another. In single-threaded programs it is possible
    to approximate the effect of `execv*` by using $(LREF spawnProcess)
    and terminating the current process once the child process has returned.
    For example:
    ---
    auto commandLine = [ "program", "arg1", "arg2" ];
    version (Posix)
    {
        execv(commandLine[0], commandLine);
        throw new Exception("Failed to execute program");
    }
    else version (Windows)
    {
        import core.stdc.stdlib : _Exit;
        _Exit(wait(spawnProcess(commandLine)));
    }
    ---
    This is, however, NOT equivalent to POSIX' `execv*`.  For one thing, the
    executed program is started as a separate process, with all this entails.
    Secondly, in a multithreaded program, other threads will continue to do
    work while the current thread is waiting for the child process to complete.

    A better option may sometimes be to terminate the current program immediately
    after spawning the child process.  This is the behaviour exhibited by the
    $(LINK2 http://msdn.microsoft.com/en-us/library/431x4c1w.aspx,`__exec`)
    functions in Microsoft's C runtime library, and it is how D's now-deprecated
    Windows `execv*` functions work. Example:
    ---
    auto commandLine = [ "program", "arg1", "arg2" ];
    version (Posix)
    {
        execv(commandLine[0], commandLine);
        throw new Exception("Failed to execute program");
    }
    else version (Windows)
    {
        spawnProcess(commandLine);
        import core.stdc.stdlib : _exit;
        _exit(0);
    }
    ---
    */
    int execv(in string pathname, in string[] argv);
    ///ditto
    int execve(in string pathname, in string[] argv, in string[] envp);
    /// ditto
    int execvp(in string pathname, in string[] argv);
    /// ditto
    int execvpe(in string pathname, in string[] argv, in string[] envp);
}
else version (Posix)
{
    int execv(in string pathname, in string[] argv)
    {
        return execv_(pathname, argv);
    }
    int execve(in string pathname, in string[] argv, in string[] envp)
    {
        return execve_(pathname, argv, envp);
    }
    int execvp(in string pathname, in string[] argv)
    {
        return execvp_(pathname, argv);
    }
    int execvpe(in string pathname, in string[] argv, in string[] envp)
    {
        return execvpe_(pathname, argv, envp);
    }
}

// Move these C declarations to druntime if we decide to keep the D wrappers
extern(C)
{
    int execv(scope const(char) *, scope const(char *)*);
    int execve(scope const(char)*, scope const(char*)*, scope const(char*)*);
    int execvp(scope const(char)*, scope const(char*)*);
    version (Windows) int execvpe(scope const(char)*, scope const(char*)*, scope const(char*)*);
}

private int execv_(in string pathname, in string[] argv)
{
    import core.exception : OutOfMemoryError;
    import std.exception : enforce;
    auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
    enforce!OutOfMemoryError(argv_ !is null, "Out of memory in std.process.");
    scope(exit) core.stdc.stdlib.free(argv_);

    toAStringz(argv, argv_);

    return execv(pathname.tempCString(), argv_);
}

private int execve_(in string pathname, in string[] argv, in string[] envp)
{
    import core.exception : OutOfMemoryError;
    import std.exception : enforce;
    auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
    enforce!OutOfMemoryError(argv_ !is null, "Out of memory in std.process.");
    scope(exit) core.stdc.stdlib.free(argv_);
    auto envp_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + envp.length));
    enforce!OutOfMemoryError(envp_ !is null, "Out of memory in std.process.");
    scope(exit) core.stdc.stdlib.free(envp_);

    toAStringz(argv, argv_);
    toAStringz(envp, envp_);

    return execve(pathname.tempCString(), argv_, envp_);
}

private int execvp_(in string pathname, in string[] argv)
{
    import core.exception : OutOfMemoryError;
    import std.exception : enforce;
    auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
    enforce!OutOfMemoryError(argv_ !is null, "Out of memory in std.process.");
    scope(exit) core.stdc.stdlib.free(argv_);

    toAStringz(argv, argv_);

    return execvp(pathname.tempCString(), argv_);
}

private int execvpe_(in string pathname, in string[] argv, in string[] envp)
{
version (Posix)
{
    import std.array : split;
    import std.conv : to;
    // Is pathname rooted?
    if (pathname[0] == '/')
    {
        // Yes, so just call execve()
        return execve(pathname, argv, envp);
    }
    else
    {
        // No, so must traverse PATHs, looking for first match
        string[]    envPaths    =   split(
            to!string(core.stdc.stdlib.getenv("PATH")), ":");
        int         iRet        =   0;

        // Note: if any call to execve() succeeds, this process will cease
        // execution, so there's no need to check the execve() result through
        // the loop.

        foreach (string pathDir; envPaths)
        {
            string  composite   =  cast(string) (pathDir ~ "/" ~ pathname);

            iRet = execve(composite, argv, envp);
        }
        if (0 != iRet)
        {
            iRet = execve(pathname, argv, envp);
        }

        return iRet;
    }
}
else version (Windows)
{
    import core.exception : OutOfMemoryError;
    import std.exception : enforce;
    auto argv_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + argv.length));
    enforce!OutOfMemoryError(argv_ !is null, "Out of memory in std.process.");
    scope(exit) core.stdc.stdlib.free(argv_);
    auto envp_ = cast(const(char)**)core.stdc.stdlib.malloc((char*).sizeof * (1 + envp.length));
    enforce!OutOfMemoryError(envp_ !is null, "Out of memory in std.process.");
    scope(exit) core.stdc.stdlib.free(envp_);

    toAStringz(argv, argv_);
    toAStringz(envp, envp_);

    return execvpe(pathname.tempCString(), argv_, envp_);
}
else
{
    static assert(0);
} // version
}

version (StdDdoc)
{
    /****************************************
     * Start up the browser and set it to viewing the page at url.
     */
    void browse(scope const(char)[] url);
}
else
version (Windows)
{
    import core.sys.windows.shellapi, core.sys.windows.winuser;

    pragma(lib,"shell32.lib");

    void browse(scope const(char)[] url) nothrow @nogc @trusted
    {
        ShellExecuteW(null, "open", url.tempCStringW(), null, null, SW_SHOWNORMAL);
    }
}
else version (Posix)
{
    import core.stdc.stdio;
    import core.stdc.string;
    import core.sys.posix.unistd;

    void browse(scope const(char)[] url) nothrow @nogc @safe
    {
        const buffer = url.tempCString(); // Retain buffer until end of scope
        const(char)*[3] args;

        // Trusted because it's called with a zero-terminated literal
        const(char)* browser = (() @trusted => core.stdc.stdlib.getenv("BROWSER"))();
        if (browser)
        {
            // String already zero-terminated
            browser = (() @trusted => strdup(browser))();
            args[0] = browser;
        }
        else
        {
            version (OSX)
            {
                args[0] = "open";
            }
            else
            {
                //args[0] = "x-www-browser";  // doesn't work on some systems
                args[0] = "xdg-open";
            }
        }

        args[1] = buffer;
        args[2] = null;

        auto childpid = core.sys.posix.unistd.fork();
        if (childpid == 0)
        {
            // Trusted because args and all entries are always zero-terminated
            (() @trusted =>
                core.sys.posix.unistd.execvp(args[0], &args[0]) ||
                perror(args[0]) // failed to execute
            )();
            return;
        }
        if (browser)
            // Trusted because it's allocated via strdup above
            (() @trusted => free(cast(void*) browser))();

        version (StdUnittest)
        {
            // Verify that the test script actually suceeds
            int status;
            const check = (() @trusted => waitpid(childpid, &status, 0))();
            assert(check != -1);
            assert(status == 0);
        }
    }
}
else
    static assert(0, "os not supported");

// Verify attributes are consistent between all implementations
@safe @nogc nothrow unittest
{
    if (false)
        browse("");
}

version (Windows) { /* Doesn't use BROWSER */ }
else
@system unittest
{
    import std.conv : text;
    import std.range : repeat;
    immutable string url = text("http://", repeat('x', 249));

    TestScript prog = `if [ "$1" != "` ~ url ~ `" ]; then exit 1; fi`;
    environment["BROWSER"] = prog.path;
    browse(url);
}
