Executes a child program asynchronously (your program will not block
waiting for the child to exit).
The child program is specified by the only argument that must be
provided,
argv.
argv should be a
Nothing-terminated array of strings, to be passed as the
argument vector for the child. The first string in
argv is of course the name of the program to execute.
By default, the name of the program must be a full path. If
flags contains the
SpawnFlagsSearchPath flag,
the
PATH environment variable is used to search for the
executable. If
flags contains the
SpawnFlagsSearchPathFromEnvp flag, the
PATH variable
from
envp is used to search for the executable. If
both the
SpawnFlagsSearchPath and
SpawnFlagsSearchPathFromEnvp flags are set, the
PATH
variable from
envp takes precedence over the
environment variable.
If the program name is not a full path and
SpawnFlagsSearchPath
flag is not used, then the program will be run from the current
directory (or
workingDirectory, if specified); this
might be unexpected or even dangerous in some cases when the current
directory is world-writable.
On Windows, note that all the string or string vector arguments to
this function and the other
g_spawn*() functions are in
UTF-8, the GLib file name encoding. Unicode characters that are not
part of the system codepage passed in these arguments will be
correctly available in the spawned program only if it uses wide
character API to retrieve its command line. For C programs built with
Microsoft's tools it is enough to make the program have a
wmain() instead of
main().
wmain() has a
wide character argument vector as parameter.
At least currently, mingw doesn't support
wmain(), so if you
use mingw to develop the spawned program, it should call
g_win32_get_command_line() to get arguments in UTF-8.
On Windows the low-level child process creation API
CreateProcess() doesn't use argument vectors, but a command
line. The C runtime library's
spawn*() family of functions
(which
spawnAsyncWithPipes eventually calls) paste the argument
vector elements together into a command line, and the C runtime
startup code does a corresponding reconstruction of an argument vector
from the command line, to be passed to
main(). Complications
arise when you have argument vector elements that contain spaces or
double quotes. The
spawn*() functions don't do any quoting or
escaping, but on the other hand the startup code does do unquoting and
unescaping in order to enable receiving arguments with embedded spaces
or double quotes. To work around this asymmetry,
spawnAsyncWithPipes will do quoting and escaping on argument
vector elements that need it before calling the C runtime
spawn() function.
The returned
childPid on Windows is a handle to the
child process, not its identifier. Process handles and process
identifiers are different concepts on Windows.
envp is a
Nothing-terminated array of strings,
where each string has the form
KEY=VALUE. This will become
the child's environment. If
envp is
Nothing,
the child inherits its parent's environment.
flags should be the bitwise OR of any flags you want
to affect the function's behaviour. The
SpawnFlagsDoNotReapChild means that the child will not
automatically be reaped; you must use a child watch
(
g_child_watch_add()) to be notified about the death
of the child process, otherwise it will stay around as a zombie
process until this process exits. Eventually you must call
spawnClosePid on the
childPid, in order to free
resources which may be associated with the child process. (On Unix,
using a child watch is equivalent to calling
waitpid()
or handling the
SIGCHLD signal manually. On Windows, calling
spawnClosePid is equivalent to calling
CloseHandle()
on the process handle returned in
childPid). See
g_child_watch_add().
Open UNIX file descriptors marked as
FD_CLOEXEC will be
automatically closed in the child process.
SpawnFlagsLeaveDescriptorsOpen means that other open file
descriptors will be inherited by the child; otherwise all descriptors
except stdin/stdout/stderr will be closed before calling
exec() in the child.
SpawnFlagsSearchPath means that
argv[0] need not be an absolute path, it will be
looked for in the
PATH environment variable.
SpawnFlagsSearchPathFromEnvp means need not be an absolute
path, it will be looked for in the
PATH variable from
envp. If both
SpawnFlagsSearchPath and
SpawnFlagsSearchPathFromEnvp are used, the value from
envp takes precedence over the environment.
SpawnFlagsChildInheritsStdin means that the child will inherit
the parent's standard input (by default, the child's standard input is
attached to
/dev/null).
SpawnFlagsStdinFromDevNull
explicitly imposes the default behavior. Both flags cannot be enabled
at the same time and, in both cases, the
stdinPipeOut
argument is ignored.
SpawnFlagsStdoutToDevNull means that the child's standard
output will be discarded (by default, it goes to the same location as
the parent's standard output).
SpawnFlagsChildInheritsStdout
explicitly imposes the default behavior. Both flags cannot be enabled
at the same time and, in both cases, the
stdoutPipeOut
argument is ignored.
SpawnFlagsStderrToDevNull means that the child's standard error
will be discarded (by default, it goes to the same location as the
parent's standard error).
SpawnFlagsChildInheritsStderr
explicitly imposes the default behavior. Both flags cannot be enabled
at the same time and, in both cases, the
stderrPipeOut
argument is ignored.
It is valid to pass the same FD in multiple parameters (e.g. you can
pass a single FD for both
stdoutFd and
stderrFd, and include it in
sourceFds
too).
sourceFds and
targetFds allow zero or
more FDs from this process to be remapped to different FDs in the
spawned process. If
nFds is greater than zero,
sourceFds and
targetFds must both be
non-
Nothing and the same length. Each FD in
sourceFds is remapped to the FD number at the same
index in
targetFds. The source and target FD may be
equal to simply propagate an FD to the spawned process. FD remappings
are processed after standard FDs, so any target FDs which equal
stdinFd,
stdoutFd or
stderrFd will overwrite them in the spawned process.
sourceFds is supported on Windows since 2.72.
SpawnFlagsFileAndArgvZero means that the first element of
argv is the file to execute, while the remaining
elements are the actual argument vector to pass to the file. Normally
spawnAsyncWithPipes uses
argv[0] as the file to
execute, and passes all of
argv to the child.
childSetup and
userData are a function
and user data. On POSIX platforms, the function is called in the child
after GLib has performed all the setup it plans to perform (including
creating pipes, closing file descriptors, etc.) but before calling
exec(). That is,
childSetup is called just
before calling
exec() in the child. Obviously actions taken
in this function will only affect the child, not the parent.
On Windows, there is no separate
fork() and
exec()
functionality. Child processes are created and run with a single API
call,
CreateProcess(). There is no sensible thing
childSetup could be used for on Windows so it is
ignored and not called.
If non-
Nothing,
childPid will on Unix be filled
with the child's process ID. You can use the process ID to send
signals to the child, or to use
g_child_watch_add()
(or
waitpid()) if you specified the
SpawnFlagsDoNotReapChild flag. On Windows,
childPid will be filled with a handle to the child
process only if you specified the
SpawnFlagsDoNotReapChild
flag. You can then access the child process using the Win32 API, for
example wait for its termination with the
WaitFor*()
functions, or examine its exit code with
GetExitCodeProcess(). You should close the handle with
CloseHandle() or
spawnClosePid when you no longer need
it.
If non-
Nothing, the
stdinPipeOut,
stdoutPipeOut,
stderrPipeOut locations
will be filled with file descriptors for writing to the child's
standard input or reading from its standard output or standard error.
The caller of
spawnAsyncWithPipes must close these file
descriptors when they are no longer in use. If these parameters are
Nothing, the corresponding pipe won't be created.
If
stdinPipeOut is
Nothing, the child's
standard input is attached to
/dev/null unless
SpawnFlagsChildInheritsStdin is set.
If
stderrPipeOut is NULL, the child's standard error
goes to the same location as the parent's standard error unless
SpawnFlagsStderrToDevNull is set.
If
stdoutPipeOut is NULL, the child's standard output
goes to the same location as the parent's standard output unless
SpawnFlagsStdoutToDevNull is set.
error can be
Nothing to ignore errors, or
non-
Nothing to report errors. If an error is set, the function
returns
False. Errors are reported even if they occur in the
child (for example if the executable in
@argv[0] is not
found). Typically the
message field of returned errors should
be displayed to users. Possible errors are those from the
G_SPAWN_ERROR domain.
If an error occurs,
childPid,
stdinPipeOut,
stdoutPipeOut, and
stderrPipeOut will not be filled with valid values.
If
childPid is not
Nothing and an error does
not occur then the returned process reference must be closed using
spawnClosePid.
On modern UNIX platforms, GLib can use an efficient process launching
codepath driven internally by
posix_spawn(). This has the
advantage of avoiding the fork-time performance costs of cloning the
parent process address space, and avoiding associated memory
overcommit checks that are not relevant in the context of immediately
executing a distinct process. This optimized codepath will be used
provided that the following conditions are met:
- SpawnFlagsDoNotReapChild is set
- SpawnFlagsLeaveDescriptorsOpen is set
- SpawnFlagsSearchPathFromEnvp is not set
- workingDirectory is Nothing
- childSetup is Nothing
- The program is of a recognised binary format, or has a shebang.
Otherwise, GLib will have to execute the program through the shell,
which is not done using the optimized codepath.
If you are writing a GTK application, and the program you are spawning
is a graphical application too, then to ensure that the spawned
program opens its windows on the right screen, you may want to use
GdkAppLaunchContext,
GAppLaunchContext, or set the
DISPLAY
environment variable.
Since: 2.68