Functions for starting and interacting with other processes, and for
working with the current process' execution environment.
The following table compactly summarises the different process creation
functions and how they relate to each other:
- @trusted Pid spawnProcess(in 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, in char[] workDir = null);
@trusted Pid spawnProcess(in char[][] args, const string[string] env, Config config = Config.none, in char[] workDir = null);
@trusted Pid spawnProcess(in 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, in char[] workDir = null);
@trusted Pid spawnProcess(in char[] program, const string[string] env, Config config = Config.none, in char[] workDir = null);
- 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 wait
on the returned Pid, 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:
- The directory from which the application loaded.
- The current directory for the parent process.
- The 32-bit Windows system directory.
- The 16-bit Windows system directory.
- The Windows directory.
- The directories listed in the PATH environment variable.
auto pid = spawnProcess("./prog");
scope(exit) wait(pid);
...
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 Config.newEnv flag is set in config, the child
process will 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 std.stdio.File 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.
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 not
one of the standard input/output/error streams of the parent process,
that stream will by default be closed in the parent process when
this function returns. See the 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.
Parameters:char[][] args |
An array which contains the program name as the zeroth element
and any command-line arguments in the following elements. |
File stdin |
The standard input stream of the child process.
This can be any std.stdio.File that is opened for reading.
By default the child process inherits the parent's input
stream. |
File stdout |
The standard output stream of the child process.
This can be any std.stdio.File that is opened for writing.
By default the child process inherits the parent's output stream. |
File stderr |
The standard error stream of the child process.
This can be any std.stdio.File that is opened for writing.
By default the child process inherits the parent's error stream. |
string[string] env |
Additional environment variables for the child process. |
Config config |
Flags that control process creation. See Config
for an overview of available flags. |
char[] workDir |
The working directory for the new process.
By default the child process inherits the parent's working
directory. |
Returns:
A Pid object that corresponds to the spawned process.
Throws:
ProcessException on failure to start the process.
std.stdio.StdioException on failure to pass one of the streams
to the child process (Windows only).
core.exception.RangeError if args is empty.
- @trusted Pid spawnShell(in char[] command, File stdin = std.stdio.stdin, File stdout = std.stdio.stdout, File stderr = std.stdio.stderr, const string[string] env = null, Config config = Config.none, in char[] workDir = null);
@trusted Pid spawnShell(in char[] command, const string[string] env, Config config = Config.none, in char[] workDir = null);
- A variation on 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 is determined by the userShell
function.
In all other respects this function works just like spawnProcess.
Please refer to the spawnProcess documentation for descriptions
of the other function parameters, the return value and any exceptions
that may be thrown.
auto pid = spawnShell(`foo "my file.txt" > foo.log`);
wait(pid);
See Also:
escapeShellCommand, which may be helpful in constructing a
properly quoted and escaped shell command line for the current platform.
- enum Config: int;
- Flags that control the behaviour of spawnProcess and
spawnShell.
Use bitwise OR to combine flags.
Example:
auto logFile = File("myapp_error.log", "w");
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();
}
- newEnv
- By default, the child process inherits the parent's environment,
and any environment variables passed to 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.
- retainStdin
retainStdout
retainStderr
- 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 spawnProcess returns. Therefore, by
default, this is done. If this is not desirable, pass any of these
options to spawnProcess.
- suppressConsole
- 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.
- inheritFDs
- On POSIX, open file descriptors
are by default inherited by the child process. As this may lead
to subtle bugs when pipes or multiple threads are involved,
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.
- class Pid;
- A handle that corresponds to a spawned process.
- const pure nothrow @property @safe int processID();
- 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 wait
has been called on the Pid, this method will return an
invalid process ID.
- pure nothrow @property @safe pid_t osHandle();
- 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 Pid.processID, while on Windows it returns
a core.sys.windows.windows.HANDLE.
Once wait has been called on the Pid, this method
will return an invalid handle.
- @safe int wait(Pid pid);
- 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. Otherwise, they may become
"zombies" – processes
that are defunct, yet still occupy a slot in the OS process table.
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 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:
ProcessException on failure.
Examples:
See the spawnProcess documentation.
See Also:
tryWait, for a non-blocking function.
- @safe auto tryWait(Pid pid);
- A non-blocking version of 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 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 wait for details).
Returns:
An std.typecons.Tuple!(bool, "terminated", int, "status").
Throws:
ProcessException on failure.
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.
- void kill(Pid pid);
void kill(Pid pid, int codeOrSignal);
- 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 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 wait to wait for a process to complete, even if kill
has been called on it.
Windows specific:
The process will be
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 codeOrSignal = 259,
as this is a special value (aka. STILL_ACTIVE)
used by Windows to signal that a process has in fact not terminated yet.
auto pid = spawnProcess("some_app");
kill(pid, 10);
assert (wait(pid) == 10);
POSIX specific:
A 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 POSIX signals are defined in core.sys.posix.signal, which corresponds to the
signal.h POSIX header. If codeOrSignal is omitted, the
SIGTERM signal will be sent. (This matches the behaviour of the
kill shell command.)
import core.sys.posix.signal: SIGKILL;
auto pid = spawnProcess("some_app");
kill(pid, SIGKILL);
assert (wait(pid) == -SIGKILL);
Throws:
ProcessException on error (e.g. if codeOrSignal is invalid).
Note that failure to terminate the process is considered a "normal"
outcome, not an error.
- @trusted Pipe pipe();
- 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");
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 pipeProcess and pipeShell for an easier
way of doing this.)
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 Pipe object that corresponds to the created pipe.
Throws:
std.stdio.StdioException on failure.
- struct Pipe;
- An interface to a pipe created by the pipe function.
- @property @trusted File readEnd();
- The read end of the pipe.
- @property @trusted File writeEnd();
- The write end of the pipe.
- @trusted void close();
- Closes both ends of the pipe.
Normally it is not necessary to do this manually, as std.stdio.File
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.)
- @trusted ProcessPipes pipeProcess(in char[][] args, Redirect redirect = Redirect.all, const string[string] env = null, Config config = Config.none, in char[] workDir = null);
@trusted ProcessPipes pipeProcess(in char[] program, Redirect redirect = Redirect.all, const string[string] env = null, Config config = Config.none, in char[] workDir = null);
@safe ProcessPipes pipeShell(in char[] command, Redirect redirect = Redirect.all, const string[string] env = null, Config config = Config.none, in char[] workDir = null);
- Starts a new process, creating pipes to redirect its standard
input, output and/or error streams.
pipeProcess and pipeShell are convenient wrappers around
spawnProcess and 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 wait on the returned 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.
Parameters:
char[][] args |
An array which contains the program name as the zeroth element
and any command-line arguments in the following elements.
(See spawnProcess for details.) |
program |
The program name, without command-line arguments.
(See spawnProcess for details.) |
command |
A shell command which is passed verbatim to the command
interpreter. (See spawnShell for details.) |
Redirect redirect |
Flags that determine which streams are redirected, and
how. See Redirect for an overview of available
flags. |
string[string] env |
Additional environment variables for the child process.
(See spawnProcess for details.) |
Config config |
Flags that control process creation. See Config
for an overview of available flags, and note that the
retainStd... flags have no effect in this function. |
char[] workDir |
The working directory for the new process.
By default the child process inherits the parent's working
directory. |
Returns:
A ProcessPipes object which contains std.stdio.File
handles that communicate with the redirected streams of the child
process, along with a Pid object that corresponds to the
spawned process.
Throws:
ProcessException on failure to start the process.
std.stdio.StdioException on failure to redirect any of the streams.
Example:
auto pipes = pipeProcess("my_application", Redirect.stdout | Redirect.stderr);
scope(exit) wait(pipes.pid);
string[] output;
foreach (line; pipes.stdout.byLine) output ~= line.idup;
string[] errors;
foreach (line; pipes.stderr.byLine) errors ~= line.idup;
- enum Redirect: int;
- Flags that can be passed to pipeProcess and pipeShell
to specify which of the child process' standard streams are redirected.
Use bitwise OR to combine flags.
- stdin
stdout
stderr
- Redirect the standard input, output or error streams, respectively.
- all
- Redirect all three streams. This is equivalent to
Redirect.stdin | Redirect.stdout | Redirect.stderr.
- stderrToStdout
- Redirect the standard error stream into the standard output stream.
This can not be combined with Redirect.stderr.
- stdoutToStderr
- Redirect the standard output stream into the standard error stream.
This can not be combined with Redirect.stdout.
- struct ProcessPipes;
- Object which contains std.stdio.File handles that allow communication
with a child process through its standard streams.
- nothrow @property @safe Pid pid();
- The Pid of the child process.
- @property @trusted File stdin();
- An std.stdio.File that allows writing to the child process'
standard input stream.
Throws:
Error if the child process' standard input stream hasn't
been redirected.
- @property @trusted File stdout();
- An std.stdio.File that allows reading from the child process'
standard output stream.
Throws:
Error if the child process' standard output stream hasn't
been redirected.
- @property @trusted File stderr();
- An std.stdio.File that allows reading from the child process'
standard error stream.
Throws:
Error if the child process' standard error stream hasn't
been redirected.
- @trusted auto execute(in char[][] args, const string[string] env = null, Config config = Config.none, size_t maxOutput = size_t.max, in char[] workDir = null);
@trusted auto execute(in char[] program, const string[string] env = null, Config config = Config.none, size_t maxOutput = size_t.max, in char[] workDir = null);
@trusted auto executeShell(in char[] command, const string[string] env = null, Config config = Config.none, size_t maxOutput = size_t.max, in char[] workDir = null);
- Executes the given program or shell command and returns its exit
code and output.
execute and executeShell start a new process using
spawnProcess and 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.
Parameters:char[][] args |
An array which contains the program name as the zeroth element
and any command-line arguments in the following elements.
(See spawnProcess for details.) |
program |
The program name, without command-line arguments.
(See spawnProcess for details.) |
command |
A shell command which is passed verbatim to the command
interpreter. (See spawnShell for details.) |
string[string] env |
Additional environment variables for the child process.
(See spawnProcess for details.) |
Config config |
Flags that control process creation. See Config
for an overview of available flags, and note that the
retainStd... flags have no effect in this function. |
size_t maxOutput |
The maximum number of bytes of output that should be
captured. |
char[] workDir |
The working directory for the new process.
By default the child process inherits the parent's working
directory. |
Returns:
An 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 wait for details.)
Throws:
ProcessException on failure to start the process.
std.stdio.StdioException on failure to capture output.
- class ProcessException: object.Exception;
- An exception that signals a problem with starting or waiting for a process.
- @property @safe string userShell();
- Determines the path to the current user's default command interpreter.
On Windows, this function returns the contents of the COMSPEC environment
variable, if it exists. Otherwise, it returns the string "cmd.exe".
On POSIX, userShell returns the contents of the SHELL environment
variable, if it exists and is non-empty. Otherwise, it returns
"/bin/sh".
- @property @trusted int thisProcessID();
- Returns the process ID number of the current process.
- string escapeShellCommand(in char[][] args...);
- Escapes an argv-style argument array to be used with spawnShell,
pipeShell or executeShell.
string url = "http://dlang.org/";
executeShell(escapeShellCommand("wget", url, "-O", "dlang-index.html"));
Concatenate multiple escapeShellCommand and
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:
Exception if any part of the command line contains unescapable
characters (NUL on all platforms, as well as CR and LF on Windows).
- pure nothrow @trusted string escapeWindowsArgument(in char[] arg);
- Quotes a command-line argument in a manner conforming to the behavior of
CommandLineToArgvW.
- pure nothrow @trusted string escapeShellFileName(in char[] fileName);
- Escapes a filename to be used for shell redirection with spawnShell,
pipeShell or executeShell.
- abstract class environment;
- 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.
- static @safe string opIndex(in char[] name);
- Retrieves the value of the environment variable with the given name.
auto path = environment["PATH"];
Throws:
Exception if the environment variable does not exist.
See Also:
environment.get, which doesn't throw on failure.
- static @safe string get(in char[] name, string defaultValue = null);
- Retrieves the value of the environment variable with the given name,
or a default value if the variable doesn't exist.
Unlike environment.opIndex, this function never throws.
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)
{
}
- static @trusted inout(char)[] opIndexAssign(inout char[] value, in char[] name);
- Assigns the given value to the environment variable with the given
name.
If the variable does not exist, it will be created. If it already exists,
it will be overwritten.
environment["foo"] = "bar";
Throws:
Exception if the environment variable could not be added
(e.g. if the name is invalid).
- static @trusted void remove(in char[] name);
- Removes the environment variable with the given name.
If the variable isn't in the environment, this function returns
successfully without doing anything.
- static @trusted string[string] toAA();
- 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:
Exception if the environment variables could not
be retrieved (Windows only).
- int system(string command);
- Execute command in a command shell.
This function is scheduled for deprecation. Please use
spawnShell or executeShell instead.
Returns:
If command is null, returns nonzero if the command
interpreter is found, and zero otherwise. If command is not
null, returns -1 on error, or the exit status of command (which may
in turn signal an error in command's execution).
Note:
On Unix systems, the homonym C function (which is accessible
to D programs as std.c.system)
returns a code in the same format as waitpid, waitpid,
meaning that C programs must use the WEXITSTATUS macro to
extract the actual exit code from the system call. D's system automatically extracts the exit status.
- int execv(in string pathname, in string[] argv);
int execve(in string pathname, in string[] argv, in string[] envp);
int execvp(in string pathname, in string[] argv);
int execvpe(in string pathname, in string[] argv, in string[] envp);
- Replace the current process by executing a command, pathname, with
the arguments in argv.
These functions are scheduled for deprecation. Please use
spawnShell instead (or, alternatively, the homonymous C
functions declared in std.c.process.)
Typically, the first element of argv is
the command being executed, i.e. argv[0] == pathname. The 'p'
versions of exec search the PATH environment variable for 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.
- alias getpid = core.sys.posix.unistd.getpid;
- Returns the process ID of the calling process, which is guaranteed to be
unique on the system. This call is always successful.
This function is scheduled for deprecation. Please use
thisProcessID instead.
Example:
writefln("Current process id: %s", getpid());
- string shell(string cmd);
- Runs cmd in a shell and returns its standard output. If
the process could not be started or exits with an error code,
throws ErrnoException.
This function is scheduled for deprecation. Please use
executeShell instead.
Example:
auto tempFilename = chomp(shell("mcookie"));
auto f = enforce(fopen(tempFilename), "w");
scope(exit)
{
fclose(f) == 0 || assert(false);
system(escapeShellCommand("rm", tempFilename));
}
... use f ...
- string getenv(in char[] name);
- Gets the value of environment variable name as a string. Calls
std.c.stdlib.getenv
internally.
This function is scheduled for deprecation. Please use
environment.get instead.
- void setenv(in char[] name, in char[] value, bool overwrite);
- Sets the value of environment variable name to value. If the
value was written, or the variable was already present and overwrite is false, returns normally. Otherwise, it throws an
exception. Calls std.c.stdlib.setenv internally.
This function is scheduled for deprecation. Please use
environment.opIndexAssign instead.
- void unsetenv(in char[] name);
- Removes variable name from the environment. Calls std.c.stdlib.unsetenv internally.
This function is scheduled for deprecation. Please use
environment.remove instead.
- void browse(string url);
- Start up the browser and set it to viewing the page at url.