Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
This contains the innards of Cliff. You probably won't need anything that's in here; Pipes.Cliff re-exports the most useful bindings. But nothing will break if you use what's in here, so it's here if you need it.
- data CmdSpec
- convertCmdSpec :: CmdSpec -> CmdSpec
- data Activity
- data HandleDesc
- data HandleOopsie = HandleOopsie Activity HandleDesc
- data Oopsie = Oopsie (Maybe HandleOopsie) CmdSpec IOException
- renderOopsie :: String -> Oopsie -> String
- defaultHandler :: Oopsie -> IO ()
- data NonPipe
- convertNonPipe :: Maybe NonPipe -> StdStream
- data CreateProcess = CreateProcess {}
- squelch :: Monad m => a -> m ()
- procSpec :: String -> [String] -> CreateProcess
- convertCreateProcess :: Maybe NonPipe -> Maybe NonPipe -> Maybe NonPipe -> CreateProcess -> CreateProcess
- data ErrSpec = ErrSpec {
- esErrorHandler :: Oopsie -> IO ()
- esCmdSpec :: CmdSpec
- makeErrSpec :: CreateProcess -> ErrSpec
- handleException :: MonadIO m => Maybe HandleOopsie -> IOException -> ErrSpec -> m ()
- handleErrors :: (MonadCatch m, MonadIO m) => Maybe HandleOopsie -> ErrSpec -> m () -> m ()
- closeHandleNoThrow :: (MonadCatch m, MonadIO m) => Handle -> HandleDesc -> ErrSpec -> m ()
- terminateProcess :: (MonadCatch m, MonadIO m) => ProcessHandle -> ErrSpec -> m ()
- acquire :: MonadSafe m => Base m a -> (a -> Base m ()) -> m a
- background :: MonadSafe m => IO a -> m (Async a)
- conveyor :: MonadSafe m => Effect (SafeT IO) () -> m ()
- waitForThread :: MonadIO m => Async a -> m a
- waitForProcess :: MonadIO m => ProcessHandle -> m ExitCode
- messageBuffer :: Buffer a
- newMailbox :: (MonadIO m, MonadSafe mi, MonadSafe mo) => m (Consumer a mi (), Producer a mo ())
- bufSize :: Int
- produceFromHandle :: (MonadSafe m, MonadCatch (Base m)) => HandleDesc -> Handle -> ErrSpec -> Producer ByteString m ()
- consumeToHandle :: (MonadSafe m, MonadCatch (Base m)) => Handle -> ErrSpec -> Consumer ByteString m ()
- backgroundSendToProcess :: MonadSafe m => Handle -> Producer ByteString (SafeT IO) () -> ErrSpec -> m ()
- backgroundReceiveFromProcess :: MonadSafe m => HandleDesc -> Handle -> Consumer ByteString (SafeT IO) () -> ErrSpec -> m ()
- runInputHandle :: (MonadSafe m, MonadSafe mi) => Handle -> ErrSpec -> m (Consumer ByteString mi ())
- runOutputHandle :: (MonadSafe m, MonadSafe mo) => HandleDesc -> Handle -> ErrSpec -> m (Producer ByteString mo ())
- createProcess :: (MonadSafe m, MonadCatch (Base m)) => CreateProcess -> ErrSpec -> m (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
- runCreateProcess :: (MonadSafe m, MonadCatch (Base m)) => Maybe NonPipe -> Maybe NonPipe -> Maybe NonPipe -> CreateProcess -> m (Maybe Handle, Maybe Handle, Maybe Handle, ErrSpec, ProcessHandle)
- pipeNone :: (MonadSafe m, MonadCatch (Base m)) => NonPipe -> NonPipe -> NonPipe -> CreateProcess -> m ProcessHandle
- pipeInput :: (MonadSafe mi, MonadSafe m, MonadCatch (Base m)) => NonPipe -> NonPipe -> CreateProcess -> m (Consumer ByteString mi (), ProcessHandle)
- pipeOutput :: (MonadSafe mo, MonadSafe m, MonadCatch (Base m)) => NonPipe -> NonPipe -> CreateProcess -> m (Producer ByteString mo (), ProcessHandle)
- pipeError :: (MonadSafe m, MonadCatch (Base m)) => NonPipe -> NonPipe -> CreateProcess -> m (Producer ByteString m (), ProcessHandle)
- pipeInputOutput :: (MonadSafe mi, MonadSafe mo, MonadSafe m, MonadCatch (Base m)) => NonPipe -> CreateProcess -> m ((Consumer ByteString mi (), Producer ByteString mo ()), ProcessHandle)
- pipeInputError :: (MonadSafe mi, MonadSafe me, MonadSafe m, MonadCatch (Base m)) => NonPipe -> CreateProcess -> m ((Consumer ByteString mi (), Producer ByteString me ()), ProcessHandle)
- pipeOutputError :: (MonadSafe mo, MonadSafe me, MonadSafe m, MonadCatch (Base m)) => NonPipe -> CreateProcess -> m ((Producer ByteString mo (), Producer ByteString me ()), ProcessHandle)
- pipeInputOutputError :: (MonadSafe mi, MonadSafe mo, MonadSafe me, MonadSafe m, MonadCatch (Base m)) => CreateProcess -> m ((Consumer ByteString mi (), Producer ByteString mo (), Producer ByteString me ()), ProcessHandle)
Data types
Like CmdSpec
in System.Process, but also has an
instance for Show
.
convertCmdSpec :: CmdSpec -> CmdSpec Source
Errors
When dealing with a Handle
, errors can occur when reading from,
writing to, or closing the handle.
data HandleDesc Source
Describes a handle. From the perspective of the subprocess; for
example, Input
means that this handle is connected to the
process's standard input.
data HandleOopsie Source
Describes IO errors tha occur when dealing with a Handle
.
Describes all IO exceptions. The Oopsie
contains the
IOException
itself, along with the CmdSpec
that was running
when the exception occurred. If the exception occurred while
dealing with a Handle
, there is also a HandleOopsie
. If there
is no HandleOopsie
, this means that the exception arose when
running terminateProcess
.
The exceptions that are caught and placed into an Oopsie
may
arise from reading data from or writing data to a Handle
. In
these errors, the associated Producer
or Consumer
will
terminate (which may trigger various cleanup actions in the
MonadSafe
computation) but the exception itself is not re-thrown;
rather, it is passed to the handler
. Similarly, an exception may
occur while closing a handle; these exceptions are caught, not
rethrown, and are passed to the handler
. If an exception arises
when terminating a process (I'm not sure this is possible) then it
is also caught, not rethrown, and passed to the handler
.
If an exception arises when creating a process--such as a command
not being found--the exception is not caught, handled, or passed
to the handler
. Also, an Oopsie
is created only for an
IOException
; no other exceptions of any kind are caught or
handled. However, exceptions of any kind will still trigger
appropriate cleanup actions in the MonadSafe
computation.
Formats an Oopsie
for display.
defaultHandler :: Oopsie -> IO () Source
The default handler when receiving an Oopsie
; simply uses
renderOopsie
to format it nicely and put it on standard error.
Configuration types
data CreateProcess Source
Like CreateProcess
in System.Process,
this gives the necessary information to create a subprocess. All
but one of these fields is also present in
CreateProcess
, and they all have the same meaning;
the only field that is different is the handler
field.
CreateProcess | |
|
squelch :: Monad m => a -> m () Source
Do not show or do anything with exceptions; useful to use as a
handler
.
:: String | The name of the program to run, such as |
-> [String] | Command-line arguments |
-> CreateProcess |
Create a CreateProcess
record with default settings. The
default settings are:
- a raw command (as opposed to a shell command) is created
- the current working directory is not changed from the parent process
- the environment is not changed from the parent process
- the parent's file descriptors (other than standard input, standard output, and standard error) are inherited
- no new process group is created
delegate_ctlc
isFalse
storeProcessHandle
isNothing
handler
isdefaultHandler
convertCreateProcess :: Maybe NonPipe -> Maybe NonPipe -> Maybe NonPipe -> CreateProcess -> CreateProcess Source
ErrSpec
Contains data necessary to deal with exceptions.
Exception handling
handleException :: MonadIO m => Maybe HandleOopsie -> IOException -> ErrSpec -> m () Source
Sends an exception using the exception handler specified in the
ErrSpec
.
handleErrors :: (MonadCatch m, MonadIO m) => Maybe HandleOopsie -> ErrSpec -> m () -> m () Source
Run an action, taking all IO errors and sending them to the handler.
closeHandleNoThrow :: (MonadCatch m, MonadIO m) => Handle -> HandleDesc -> ErrSpec -> m () Source
Close a handle. Catches any exceptions and passes them to the handler.
terminateProcess :: (MonadCatch m, MonadIO m) => ProcessHandle -> ErrSpec -> m () Source
Terminates a process; sends any IO errors to the handler.
Acquires a resource and ensures it will be destroyed when the
MonadSafe
computation completes.
Threads
background :: MonadSafe m => IO a -> m (Async a) Source
Runs a thread in the background. The thread is terminated when
the MonadSafe
computation completes.
conveyor :: MonadSafe m => Effect (SafeT IO) () -> m () Source
Runs in the background an effect, typically one that is moving
data from one process to another. For examples of its usage, see
Pipes.Cliff.Examples. The associated thread is killed when the
MonadSafe
computation completes.
waitForThread :: MonadIO m => Async a -> m a Source
A version of wait
with an overloaded
MonadIO
return type. Allows you to wait for the return value of
threads launched with background
. If the thread throws an
exception, waitForThread
will throw that same exception.
waitForProcess :: MonadIO m => ProcessHandle -> m ExitCode Source
An overloaded version of the waitForProcess
from
System.Process.
Mailboxes
messageBuffer :: Buffer a Source
A buffer that holds 1 message. I have no idea if this is the ideal size. Don't use an unbounded buffer, though, because with unbounded producers an unbounded buffer will fill up your RAM.
Since the buffer just holds one size, you might think "why not
just use an MVar"? At least, I have been silly enough to think
that. Using Pipes.Concurrent
also give the mailbox the ability
to be sealed; sealing the mailbox signals to the other side that it
won't be getting any more input or be allowed to send any more
output, which tells the whole pipeline to start shutting down.
newMailbox :: (MonadIO m, MonadSafe mi, MonadSafe mo) => m (Consumer a mi (), Producer a mo ()) Source
Creates a new mailbox and returns Proxy
that stream values
into and out of the mailbox. Each Proxy
is equipped with a
finalizer that will seal the mailbox immediately after production
or consumption has completed, even if such completion is not due
to an exhausted mailbox. This will signal to the other side of
the mailbox that the mailbox is sealed.
Production from and consumption to Handle
s
I have no idea what this should be. I'll start with a simple small value and see how it works.
produceFromHandle :: (MonadSafe m, MonadCatch (Base m)) => HandleDesc -> Handle -> ErrSpec -> Producer ByteString m () Source
consumeToHandle :: (MonadSafe m, MonadCatch (Base m)) => Handle -> ErrSpec -> Consumer ByteString m () Source
backgroundSendToProcess :: MonadSafe m => Handle -> Producer ByteString (SafeT IO) () -> ErrSpec -> m () Source
Creates a background thread that will consume to the given Handle
from the given Producer. Takes ownership of the Handle
and
closes it when done.
backgroundReceiveFromProcess :: MonadSafe m => HandleDesc -> Handle -> Consumer ByteString (SafeT IO) () -> ErrSpec -> m () Source
Creates a background thread that will produce from the given Handle into the given Consumer. Takes possession of the Handle and closes it when done.
runInputHandle :: (MonadSafe m, MonadSafe mi) => Handle -> ErrSpec -> m (Consumer ByteString mi ()) Source
Does everything necessary to run a Handle
that is created to a
process standard input. Creates mailbox, runs background thread
that pumps data out of the mailbox and into the process standard
input, and returns a Consumer that consumes and places what it
consumes into the mailbox for delivery to the background process.
runOutputHandle :: (MonadSafe m, MonadSafe mo) => HandleDesc -> Handle -> ErrSpec -> m (Producer ByteString mo ()) Source
Creating subprocesses
createProcess :: (MonadSafe m, MonadCatch (Base m)) => CreateProcess -> ErrSpec -> m (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) Source
Creates a subprocess. Registers destroyers for each handle created, as well as for the ProcessHandle.
:: (MonadSafe m, MonadCatch (Base m)) | |
=> Maybe NonPipe | Standard input |
-> Maybe NonPipe | Standard output |
-> Maybe NonPipe | Standard error |
-> CreateProcess | |
-> m (Maybe Handle, Maybe Handle, Maybe Handle, ErrSpec, ProcessHandle) |
Convenience wrapper for createProcess
. The subprocess is
terminated and all its handles destroyed when the MonadSafe
computation completes.
Creating Proxy
:: (MonadSafe m, MonadCatch (Base m)) | |
=> NonPipe | Standard input |
-> NonPipe | Standard output |
-> NonPipe | Standard error |
-> CreateProcess | |
-> m ProcessHandle |
Do not create any Proxy
to or from the process.
:: (MonadSafe mi, MonadSafe m, MonadCatch (Base m)) | |
=> NonPipe | Standard output |
-> NonPipe | Standard error |
-> CreateProcess | |
-> m (Consumer ByteString mi (), ProcessHandle) | A |
Create a Consumer
for standard input.
:: (MonadSafe mo, MonadSafe m, MonadCatch (Base m)) | |
=> NonPipe | Standard input |
-> NonPipe | Standard error |
-> CreateProcess | |
-> m (Producer ByteString mo (), ProcessHandle) | A |
Create a Producer
for standard output.
:: (MonadSafe m, MonadCatch (Base m)) | |
=> NonPipe | Standard input |
-> NonPipe | Standard output |
-> CreateProcess | |
-> m (Producer ByteString m (), ProcessHandle) | A |
Create a Producer
for standard error.
:: (MonadSafe mi, MonadSafe mo, MonadSafe m, MonadCatch (Base m)) | |
=> NonPipe | Standard error |
-> CreateProcess | |
-> m ((Consumer ByteString mi (), Producer ByteString mo ()), ProcessHandle) | A |
:: (MonadSafe mi, MonadSafe me, MonadSafe m, MonadCatch (Base m)) | |
=> NonPipe | Standard output |
-> CreateProcess | |
-> m ((Consumer ByteString mi (), Producer ByteString me ()), ProcessHandle) | A |
:: (MonadSafe mo, MonadSafe me, MonadSafe m, MonadCatch (Base m)) | |
=> NonPipe | Standard input |
-> CreateProcess | |
-> m ((Producer ByteString mo (), Producer ByteString me ()), ProcessHandle) | A |
:: (MonadSafe mi, MonadSafe mo, MonadSafe me, MonadSafe m, MonadCatch (Base m)) | |
=> CreateProcess | |
-> m ((Consumer ByteString mi (), Producer ByteString mo (), Producer ByteString me ()), ProcessHandle) | A |