Copyright | Will Thompson Iñaki García Etxebarria and Jonas Platte |
---|---|
License | LGPL-2.1 |
Maintainer | Iñaki García Etxebarria (garetxe@gmail.com) |
Safe Haskell | None |
Language | Haskell2010 |
- Exported types
- Methods
- communicate
- communicateAsync
- communicateFinish
- communicateUtf8
- communicateUtf8Async
- communicateUtf8Finish
- forceExit
- getExitStatus
- getIdentifier
- getIfExited
- getIfSignaled
- getStatus
- getStderrPipe
- getStdinPipe
- getStdoutPipe
- getSuccessful
- getTermSig
- new
- sendSignal
- wait
- waitAsync
- waitCheck
- waitCheckAsync
- waitCheckFinish
- waitFinish
- Properties
Subprocess
allows the creation of and interaction with child
processes.
Processes can be communicated with using standard GIO-style APIs (ie:
InputStream
, OutputStream
). There are GIO-style APIs to wait for
process termination (ie: cancellable and with an asynchronous
variant).
There is an API to force a process to terminate, as well as a race-free API for sending UNIX signals to a subprocess.
One major advantage that GIO brings over the core GLib library is
comprehensive API for asynchronous I/O, such
outputStreamSpliceAsync
. This makes GSubprocess
significantly more powerful and flexible than equivalent APIs in
some other languages such as the subprocess.py
included with Python. For example, using Subprocess
one could
create two child processes, reading standard output from the first,
processing it, and writing to the input stream of the second, all
without blocking the main loop.
A powerful subprocessCommunicate
API is provided similar to the
communicate()
method of subprocess.py
. This enables very easy
interaction with a subprocess that has been opened with pipes.
Subprocess
defaults to tight control over the file descriptors open
in the child process, avoiding dangling-fd issues that are caused by
a simple fork()
/exec()
. The only open file descriptors in the
spawned process are ones that were explicitly specified by the
Subprocess
API (unless SubprocessFlagsInheritFds
was
specified).
Subprocess
will quickly reap all child processes as they exit,
avoiding "zombie processes" remaining around for long periods of
time. subprocessWait
can be used to wait for this to happen,
but it will happen even without the call being explicitly made.
As a matter of principle, Subprocess
has no API that accepts
shell-style space-separated strings. It will, however, match the
typical shell behaviour of searching the PATH for executables that do
not contain a directory separator in their name.
Subprocess
attempts to have a very simple API for most uses (ie:
spawning a subprocess with arguments and support for most typical
kinds of input and output redirection). See g_subprocess_new()
. The
SubprocessLauncher
API is provided for more complicated cases
(advanced types of redirection, environment variable manipulation,
change of working directory, child setup functions, etc).
A typical use of Subprocess
will involve calling
g_subprocess_new()
, followed by subprocessWaitAsync
or
subprocessWait
. After the process exits, the status can be
checked using functions such as subprocessGetIfExited
(which
are similar to the familiar WIFEXITED-style POSIX macros).
Since: 2.40
Synopsis
- newtype Subprocess = Subprocess (ManagedPtr Subprocess)
- class GObject o => IsSubprocess o
- toSubprocess :: (MonadIO m, IsSubprocess o) => o -> m Subprocess
- noSubprocess :: Maybe Subprocess
- subprocessCommunicate :: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) => a -> Maybe Bytes -> Maybe b -> m (Maybe Bytes, Maybe Bytes)
- subprocessCommunicateAsync :: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) => a -> Maybe Bytes -> Maybe b -> Maybe AsyncReadyCallback -> m ()
- subprocessCommunicateFinish :: (HasCallStack, MonadIO m, IsSubprocess a, IsAsyncResult b) => a -> b -> m (Maybe Bytes, Maybe Bytes)
- subprocessCommunicateUtf8 :: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) => a -> Maybe Text -> Maybe b -> m (Maybe Text, Maybe Text)
- subprocessCommunicateUtf8Async :: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) => a -> Maybe Text -> Maybe b -> Maybe AsyncReadyCallback -> m ()
- subprocessCommunicateUtf8Finish :: (HasCallStack, MonadIO m, IsSubprocess a, IsAsyncResult b) => a -> b -> m (Maybe Text, Maybe Text)
- subprocessForceExit :: (HasCallStack, MonadIO m, IsSubprocess a) => a -> m ()
- subprocessGetExitStatus :: (HasCallStack, MonadIO m, IsSubprocess a) => a -> m Int32
- subprocessGetIdentifier :: (HasCallStack, MonadIO m, IsSubprocess a) => a -> m Text
- subprocessGetIfExited :: (HasCallStack, MonadIO m, IsSubprocess a) => a -> m Bool
- subprocessGetIfSignaled :: (HasCallStack, MonadIO m, IsSubprocess a) => a -> m Bool
- subprocessGetStatus :: (HasCallStack, MonadIO m, IsSubprocess a) => a -> m Int32
- subprocessGetStderrPipe :: (HasCallStack, MonadIO m, IsSubprocess a) => a -> m InputStream
- subprocessGetStdinPipe :: (HasCallStack, MonadIO m, IsSubprocess a) => a -> m OutputStream
- subprocessGetStdoutPipe :: (HasCallStack, MonadIO m, IsSubprocess a) => a -> m InputStream
- subprocessGetSuccessful :: (HasCallStack, MonadIO m, IsSubprocess a) => a -> m Bool
- subprocessGetTermSig :: (HasCallStack, MonadIO m, IsSubprocess a) => a -> m Int32
- subprocessNew :: (HasCallStack, MonadIO m) => [[Char]] -> [SubprocessFlags] -> m Subprocess
- subprocessSendSignal :: (HasCallStack, MonadIO m, IsSubprocess a) => a -> Int32 -> m ()
- subprocessWait :: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) => a -> Maybe b -> m ()
- subprocessWaitAsync :: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) => a -> Maybe b -> Maybe AsyncReadyCallback -> m ()
- subprocessWaitCheck :: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) => a -> Maybe b -> m ()
- subprocessWaitCheckAsync :: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) => a -> Maybe b -> Maybe AsyncReadyCallback -> m ()
- subprocessWaitCheckFinish :: (HasCallStack, MonadIO m, IsSubprocess a, IsAsyncResult b) => a -> b -> m ()
- subprocessWaitFinish :: (HasCallStack, MonadIO m, IsSubprocess a, IsAsyncResult b) => a -> b -> m ()
- constructSubprocessArgv :: IsSubprocess o => [Text] -> IO (GValueConstruct o)
- constructSubprocessFlags :: IsSubprocess o => [SubprocessFlags] -> IO (GValueConstruct o)
Exported types
newtype Subprocess Source #
Memory-managed wrapper type.
Instances
GObject Subprocess Source # | |
Defined in GI.Gio.Objects.Subprocess gobjectType :: Subprocess -> IO GType # | |
IsObject Subprocess Source # | |
Defined in GI.Gio.Objects.Subprocess | |
IsInitable Subprocess Source # | |
Defined in GI.Gio.Objects.Subprocess | |
IsSubprocess Subprocess Source # | |
Defined in GI.Gio.Objects.Subprocess |
class GObject o => IsSubprocess o Source #
Type class for types which can be safely cast to Subprocess
, for instance with toSubprocess
.
Instances
(GObject a, (UnknownAncestorError Subprocess a :: Constraint)) => IsSubprocess a Source # | |
Defined in GI.Gio.Objects.Subprocess | |
IsSubprocess Subprocess Source # | |
Defined in GI.Gio.Objects.Subprocess |
toSubprocess :: (MonadIO m, IsSubprocess o) => o -> m Subprocess Source #
Cast to Subprocess
, for types for which this is known to be safe. For general casts, use castTo
.
noSubprocess :: Maybe Subprocess Source #
A convenience alias for Nothing
:: Maybe
Subprocess
.
Methods
communicate
subprocessCommunicate Source #
:: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) | |
=> a |
|
-> Maybe Bytes |
|
-> Maybe b |
|
-> m (Maybe Bytes, Maybe Bytes) | (Can throw |
Communicate with the subprocess until it terminates, and all input and output has been completed.
If stdinBuf
is given, the subprocess must have been created with
SubprocessFlagsStdinPipe
. The given data is fed to the
stdin of the subprocess and the pipe is closed (ie: EOF).
At the same time (as not to cause blocking when dealing with large
amounts of data), if SubprocessFlagsStdoutPipe
or
SubprocessFlagsStderrPipe
were used, reads from those
streams. The data that was read is returned in stdout
and/or
the stderr
.
If the subprocess was created with SubprocessFlagsStdoutPipe
,
stdoutBuf
will contain the data read from stdout. Otherwise, for
subprocesses not created with SubprocessFlagsStdoutPipe
,
stdoutBuf
will be set to Nothing
. Similar provisions apply to
stderrBuf
and SubprocessFlagsStderrPipe
.
As usual, any output variable may be given as Nothing
to ignore it.
If you desire the stdout and stderr data to be interleaved, create
the subprocess with SubprocessFlagsStdoutPipe
and
SubprocessFlagsStderrMerge
. The merged result will be returned
in stdoutBuf
and stderrBuf
will be set to Nothing
.
In case of any error (including cancellation), False
will be
returned with error
set. Some or all of the stdin data may have
been written. Any stdout or stderr data that has been read will be
discarded. None of the out variables (aside from error
) will have
been set to anything in particular and should not be inspected.
In the case that True
is returned, the subprocess has exited and the
exit status inspection APIs (eg: subprocessGetIfExited
,
subprocessGetExitStatus
) may be used.
You should not attempt to use any of the subprocess pipes after starting this function, since they may be left in strange states, even if the operation was cancelled. You should especially not attempt to interact with the pipes while the operation is in progress (either from another thread or if using the asynchronous version).
Since: 2.40
communicateAsync
subprocessCommunicateAsync Source #
:: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) | |
=> a |
|
-> Maybe Bytes |
|
-> Maybe b |
|
-> Maybe AsyncReadyCallback |
|
-> m () |
Asynchronous version of subprocessCommunicate
. Complete
invocation with subprocessCommunicateFinish
.
communicateFinish
subprocessCommunicateFinish Source #
:: (HasCallStack, MonadIO m, IsSubprocess a, IsAsyncResult b) | |
=> a |
|
-> b |
|
-> m (Maybe Bytes, Maybe Bytes) | (Can throw |
Complete an invocation of subprocessCommunicateAsync
.
communicateUtf8
subprocessCommunicateUtf8 Source #
:: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) | |
=> a |
|
-> Maybe Text |
|
-> Maybe b |
|
-> m (Maybe Text, Maybe Text) | (Can throw |
Like subprocessCommunicate
, but validates the output of the
process as UTF-8, and returns it as a regular NUL terminated string.
communicateUtf8Async
subprocessCommunicateUtf8Async Source #
:: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) | |
=> a |
|
-> Maybe Text |
|
-> Maybe b |
|
-> Maybe AsyncReadyCallback |
|
-> m () |
Asynchronous version of subprocessCommunicateUtf8
. Complete
invocation with subprocessCommunicateUtf8Finish
.
communicateUtf8Finish
subprocessCommunicateUtf8Finish Source #
:: (HasCallStack, MonadIO m, IsSubprocess a, IsAsyncResult b) | |
=> a |
|
-> b |
|
-> m (Maybe Text, Maybe Text) | (Can throw |
Complete an invocation of subprocessCommunicateUtf8Async
.
forceExit
:: (HasCallStack, MonadIO m, IsSubprocess a) | |
=> a |
|
-> m () |
Use an operating-system specific method to attempt an immediate,
forceful termination of the process. There is no mechanism to
determine whether or not the request itself was successful;
however, you can use subprocessWait
to monitor the status of
the process after calling this function.
On Unix, this function sends SIGKILL
.
Since: 2.40
getExitStatus
subprocessGetExitStatus Source #
:: (HasCallStack, MonadIO m, IsSubprocess a) | |
=> a |
|
-> m Int32 | Returns: the exit status |
Check the exit status of the subprocess, given that it exited
normally. This is the value passed to the exit()
system call or the
return value from main.
This is equivalent to the system WEXITSTATUS macro.
It is an error to call this function before subprocessWait
and
unless subprocessGetIfExited
returned True
.
Since: 2.40
getIdentifier
subprocessGetIdentifier Source #
:: (HasCallStack, MonadIO m, IsSubprocess a) | |
=> a |
|
-> m Text |
On UNIX, returns the process ID as a decimal string.
On Windows, returns the result of GetProcessId()
also as a string.
getIfExited
subprocessGetIfExited Source #
:: (HasCallStack, MonadIO m, IsSubprocess a) | |
=> a |
|
-> m Bool | Returns: |
Check if the given subprocess exited normally (ie: by way of exit()
or return from main()
).
This is equivalent to the system WIFEXITED macro.
It is an error to call this function before subprocessWait
has
returned.
Since: 2.40
getIfSignaled
subprocessGetIfSignaled Source #
:: (HasCallStack, MonadIO m, IsSubprocess a) | |
=> a |
|
-> m Bool | Returns: |
Check if the given subprocess terminated in response to a signal.
This is equivalent to the system WIFSIGNALED macro.
It is an error to call this function before subprocessWait
has
returned.
Since: 2.40
getStatus
:: (HasCallStack, MonadIO m, IsSubprocess a) | |
=> a |
|
-> m Int32 | Returns: the (meaningless) |
Gets the raw status code of the process, as from waitpid()
.
This value has no particular meaning, but it can be used with the
macros defined by the system headers such as WIFEXITED. It can also
be used with spawnCheckExitStatus
.
It is more likely that you want to use subprocessGetIfExited
followed by subprocessGetExitStatus
.
It is an error to call this function before subprocessWait
has
returned.
Since: 2.40
getStderrPipe
subprocessGetStderrPipe Source #
:: (HasCallStack, MonadIO m, IsSubprocess a) | |
=> a |
|
-> m InputStream | Returns: the stderr pipe |
Gets the InputStream
from which to read the stderr output of
subprocess
.
The process must have been created with
SubprocessFlagsStderrPipe
.
Since: 2.40
getStdinPipe
subprocessGetStdinPipe Source #
:: (HasCallStack, MonadIO m, IsSubprocess a) | |
=> a |
|
-> m OutputStream | Returns: the stdout pipe |
Gets the OutputStream
that you can write to in order to give data
to the stdin of subprocess
.
The process must have been created with
SubprocessFlagsStdinPipe
.
Since: 2.40
getStdoutPipe
subprocessGetStdoutPipe Source #
:: (HasCallStack, MonadIO m, IsSubprocess a) | |
=> a |
|
-> m InputStream | Returns: the stdout pipe |
Gets the InputStream
from which to read the stdout output of
subprocess
.
The process must have been created with
SubprocessFlagsStdoutPipe
.
Since: 2.40
getSuccessful
subprocessGetSuccessful Source #
:: (HasCallStack, MonadIO m, IsSubprocess a) | |
=> a |
|
-> m Bool | Returns: |
Checks if the process was "successful". A process is considered
successful if it exited cleanly with an exit status of 0, either by
way of the exit()
system call or return from main()
.
It is an error to call this function before subprocessWait
has
returned.
Since: 2.40
getTermSig
:: (HasCallStack, MonadIO m, IsSubprocess a) | |
=> a |
|
-> m Int32 | Returns: the signal causing termination |
Get the signal number that caused the subprocess to terminate, given that it terminated due to a signal.
This is equivalent to the system WTERMSIG macro.
It is an error to call this function before subprocessWait
and
unless subprocessGetIfSignaled
returned True
.
Since: 2.40
new
:: (HasCallStack, MonadIO m) | |
=> [[Char]] |
|
-> [SubprocessFlags] |
|
-> m Subprocess | Returns: A newly created |
Create a new process with the given flags and argument list.
The argument list is expected to be Nothing
-terminated.
Since: 2.40
sendSignal
:: (HasCallStack, MonadIO m, IsSubprocess a) | |
=> a |
|
-> Int32 |
|
-> m () |
Sends the UNIX signal signalNum
to the subprocess, if it is still
running.
This API is race-free. If the subprocess has terminated, it will not be signalled.
This API is not available on Windows.
Since: 2.40
wait
:: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) | |
=> a |
|
-> Maybe b |
|
-> m () | (Can throw |
Synchronously wait for the subprocess to terminate.
After the process terminates you can query its exit status with
functions such as subprocessGetIfExited
and
subprocessGetExitStatus
.
This function does not fail in the case of the subprocess having
abnormal termination. See subprocessWaitCheck
for that.
Cancelling cancellable
doesn't kill the subprocess. Call
subprocessForceExit
if it is desirable.
Since: 2.40
waitAsync
:: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) | |
=> a |
|
-> Maybe b |
|
-> Maybe AsyncReadyCallback |
|
-> m () |
waitCheck
:: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) | |
=> a |
|
-> Maybe b |
|
-> m () | (Can throw |
Combines subprocessWait
with spawnCheckExitStatus
.
Since: 2.40
waitCheckAsync
subprocessWaitCheckAsync Source #
:: (HasCallStack, MonadIO m, IsSubprocess a, IsCancellable b) | |
=> a |
|
-> Maybe b |
|
-> Maybe AsyncReadyCallback |
|
-> m () |
Combines subprocessWaitAsync
with spawnCheckExitStatus
.
This is the asynchronous version of subprocessWaitCheck
.
Since: 2.40
waitCheckFinish
subprocessWaitCheckFinish Source #
:: (HasCallStack, MonadIO m, IsSubprocess a, IsAsyncResult b) | |
=> a |
|
-> b |
|
-> m () | (Can throw |
Collects the result of a previous call to
subprocessWaitCheckAsync
.
Since: 2.40
waitFinish
:: (HasCallStack, MonadIO m, IsSubprocess a, IsAsyncResult b) | |
=> a |
|
-> b |
|
-> m () | (Can throw |
Collects the result of a previous call to
subprocessWaitAsync
.
Since: 2.40
Properties
argv
No description available in the introspection data.
constructSubprocessArgv :: IsSubprocess o => [Text] -> IO (GValueConstruct o) Source #
Construct a GValueConstruct
with valid value for the “argv
” property. This is rarely needed directly, but it is used by new
.
flags
No description available in the introspection data.
constructSubprocessFlags :: IsSubprocess o => [SubprocessFlags] -> IO (GValueConstruct o) Source #
Construct a GValueConstruct
with valid value for the “flags
” property. This is rarely needed directly, but it is used by new
.