-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Streaming to and from subprocesses using Pipes
--   
--   pipes-cliff helps you spawn subprocesses and send data to and from
--   them with the Pipes library. Subprocesses are opened using the process
--   library, and you stream data in and out using the various Pipes
--   abstractions.
--   
--   Though this library uses the Pipes library, I have not coordinated
--   with the author of the Pipes library in any way. Any bugs or design
--   flaws are mine and should be reported to
--   
--   <a>http://www.github.com/massysett/pipes-cliff/issues</a>
--   
--   For more information, see the README.md file, which is located in the
--   source tarball and at
--   
--   <a>https://github.com/massysett/pipes-cliff</a>
@package pipes-cliff
@version 0.12.0.0


-- | This contains the innards of Cliff. You shouldn't need anything that's
--   in this module; instead, use <a>Pipes.Cliff</a>.
--   
--   Exit code and waiting for processes: as of base 4.7, there was a bug
--   in <a>waitForProcess</a> which may arise if you have multiple threads
--   waiting for a single process to finish. Thus this module is set up so
--   that only one thread does the wait, and it places the result in an
--   MVar. See
--   
--   <a>http://ghc.haskell.org/trac/ghc/ticket/9292</a>
module Pipes.Cliff.Core

-- | Like <a>CmdSpec</a> in <a>System.Process</a>, but also has an instance
--   for <a>Show</a>.
data CmdSpec
ShellCommand :: String -> CmdSpec
RawCommand :: FilePath -> [String] -> CmdSpec
convertCmdSpec :: CmdSpec -> CmdSpec

-- | When dealing with a <a>Handle</a>, errors can occur when reading from,
--   writing to, or closing the handle.
data Activity
Reading :: Activity
Writing :: Activity
Closing :: Activity

-- | The two kinds of outbound handles.
data Outbound
Output :: Outbound
Error :: Outbound

-- | Describes a handle. From the perspective of the subprocess; for
--   example, <a>Input</a> means that this handle is connected to the
--   process's standard input.
data HandleDesc
Input :: HandleDesc
Outbound :: Outbound -> HandleDesc

-- | Describes all IO exceptions. The <a>Oopsie</a> contains the
--   <a>IOException</a> itself, along with the <a>CmdSpec</a> that was
--   running when the exception occurred.
--   
--   The exceptions that are caught and placed into an <a>Oopsie</a> may
--   arise from reading data from or writing data to a <a>Handle</a>. In
--   these errors, the associated <a>Producer</a> or <a>Consumer</a> will
--   terminate (which may trigger various cleanup actions in the
--   <a>MonadSafe</a> computation) but the exception itself is not
--   re-thrown; rather, it is passed to the <a>handler</a>. Similarly, an
--   exception may occur while closing a handle; these exceptions are
--   caught, not rethrown, and are passed to the <a>handler</a>. 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
--   <a>handler</a>.
--   
--   If an exception arises when creating a process--such as a command not
--   being found--the exception is <i>not</i> caught, handled, or passed to
--   the <a>handler</a>. In addition, no exceptions are caught if they
--   originated during a <a>waitForProcess</a>. (I can't conceive of how
--   any synchronous exceptions could arise from <a>waitForProcess</a>, but
--   if they do, Cliff does not handle them.) Also, an <a>Oopsie</a> is
--   created only for an <a>IOException</a>; no other exceptions of any
--   kind are caught or handled. However, exceptions of any kind will still
--   trigger appropriate cleanup actions in the <a>MonadSafe</a>
--   computation.
data Oopsie
Oopsie :: Activity -> HandleDesc -> CmdSpec -> IOException -> Oopsie

-- | Formats an <a>Oopsie</a> for display.
renderOopsie :: String -> Oopsie -> String

-- | The default handler when receiving an <a>Oopsie</a>; simply uses
--   <a>renderOopsie</a> to format it nicely and put it on standard error.
--   
--   Side effects: gets the program name from the environment, and prints
--   the Oopsie to standard error.
defaultHandler :: Oopsie -> IO ()

-- | How will the subprocess get its information for this stream? A
--   <a>NonPipe</a> is used for streams that will not be assigned to a
--   <a>Proxy</a> but, instead, will be inherited from the parent or
--   directed from an existing <a>Handle</a>.
data NonPipe

-- | Use whatever stream that the parent process has.
Inherit :: NonPipe

-- | Use the given handle for input or output
UseHandle :: Handle -> NonPipe
convertNonPipe :: Maybe NonPipe -> StdStream

-- | Like <a>CreateProcess</a> in <a>System.Process</a>, this gives the
--   necessary information to create a subprocess. All but one of these
--   fields is also present in <a>CreateProcess</a>, and they all have the
--   same meaning; the only field that is different is the <a>handler</a>
--   field.
data CreateProcess
CreateProcess :: CmdSpec -> Maybe FilePath -> Maybe [(String, String)] -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe GroupID -> Maybe UserID -> (Oopsie -> IO ()) -> CreateProcess

-- | Executable and arguments, or shell command
[cmdspec] :: CreateProcess -> CmdSpec

-- | A new current working directory for the subprocess; if <a>Nothing</a>,
--   use the calling process's working directory.
[cwd] :: CreateProcess -> Maybe FilePath

-- | The environment for the subprocess; if <a>Nothing</a>, use the calling
--   process's working directory.
[env] :: CreateProcess -> Maybe [(String, String)]

-- | If <a>True</a>, close all file descriptors other than the standard
--   descriptors. See the documentation for <a>close_fds</a> for details on
--   how this works in Windows.
[close_fds] :: CreateProcess -> Bool

-- | If <a>True</a>, create a new process group.
[create_group] :: CreateProcess -> Bool

-- | See <a>delegate_ctlc</a> in the <a>System.Process</a> module for
--   details.
[delegate_ctlc] :: CreateProcess -> Bool

-- | Use the windows DETACHED_PROCESS flag when creating the process; does
--   nothing on other platforms.
[detach_console] :: CreateProcess -> Bool

-- | Use the windows CREATE_NEW_CONSOLE flag when creating the process;
--   does nothing on other platforms.
[create_new_console] :: CreateProcess -> Bool

-- | Use posix setsid to start the new process in a new session; does
--   nothing on other platforms.
[new_session] :: CreateProcess -> Bool

-- | Use posix setgid to set child process's group id; does nothing on
--   other platforms.
[child_group] :: CreateProcess -> Maybe GroupID

-- | Use posix setuid to set child process's user id; does nothing on other
--   platforms.
[child_user] :: CreateProcess -> Maybe UserID

-- | Whenever an IO exception arises during the course of various IO
--   actions, the exception is caught and placed into an <a>Oopsie</a> that
--   indicates why and where the exception happened. The <a>handler</a>
--   determines what happens when an <a>Oopsie</a> comes in. See
--   <a>Oopsie</a> for details.
--   
--   The default <a>handler</a> created by <a>procSpec</a> is
--   <a>defaultHandler</a>, which will simply print the exceptions to
--   standard error. You may not want to see the exceptions at all. For
--   example, many exceptions come from broken pipes. A broken pipe might
--   be entirely normal in your circumstance. For example, if you are
--   streaming a large set of values to a pager such as <tt>less</tt> and
--   you expect that the user will often quit the pager without viewing the
--   whole result, a broken pipe will result, which will print a warning
--   message. That can be a nuisance.
--   
--   If you don't want to see the exceptions at all, just set
--   <a>handler</a> to <a>squelch</a>, which simply discards the
--   exceptions.
--   
--   Conceivably you could rig up an elaborate mechanism that puts the
--   <a>Oopsie</a>s into a <a>Pipes.Concurrent</a> mailbox or something.
--   Indeed, when using <a>defaultHandler</a> each thread will print its
--   warnings to standard error at any time. If you are using multiple
--   processes and each prints warnings at the same time, total gibberish
--   can result as the text gets mixed in. You could solve this by putting
--   the errors into a <a>Pipes.Concurrent</a> mailbox and having a single
--   thread print the errors; this sort of thing could be built into the
--   library but so far I haven't been motivated to do it.
[handler] :: CreateProcess -> Oopsie -> IO ()

-- | Do not show or do anything with exceptions; useful to use as a
--   <a>handler</a>.
--   
--   Side effects: None.
squelch :: Monad m => a -> m ()

-- | Create a <a>CreateProcess</a> record with default settings. The
--   default settings are:
--   
--   <ul>
--   <li>a raw command (as opposed to a shell command) is created</li>
--   <li>the current working directory is not changed from the parent
--   process</li>
--   <li>the environment is not changed from the parent process</li>
--   <li>the parent's file descriptors (other than standard input, standard
--   output, and standard error) are inherited</li>
--   <li>no new process group is created</li>
--   <li><a>delegate_ctlc</a>, <a>detach_console</a>,
--   <a>create_new_console</a>, and <a>new_session</a> are all
--   <a>False</a></li>
--   <li><a>child_group</a> and <a>child_user</a> are both
--   <a>Nothing</a></li>
--   <li><a>handler</a> is <a>defaultHandler</a></li>
--   </ul>
procSpec :: String -> [String] -> CreateProcess
convertCreateProcess :: Maybe NonPipe -> Maybe NonPipe -> Maybe NonPipe -> CreateProcess -> CreateProcess

-- | Guarantees single-thread access
--   
--   All MVar idioms thanks to Neil Mitchell:
--   <a>http://neilmitchell.blogspot.com/2012/06/flavours-of-mvar_04.html</a>
type Lock = MVar ()
newLock :: IO Lock
withLock :: Lock -> IO a -> IO a

-- | Operates on mutable variables in thread-safe way.
type Var a = MVar a
newVar :: a -> IO (Var a)
modifyVar :: Var a -> (a -> IO (a, b)) -> IO b
modifyVar_ :: Var a -> (a -> IO a) -> IO ()
readVar :: Var a -> IO a

-- | Starts with no value, is written to once, and is read one or more
--   times.
type Barrier a = MVar a
newBarrier :: IO (Barrier a)
signalBarrier :: Barrier a -> a -> IO ()
waitBarrier :: Barrier a -> IO a

-- | Takes an action and returns a new action. If the action is never
--   called the argument action will never be executed, but if it is called
--   more than once, it will only be executed once.
--   
--   Side effects: creates a <a>Var</a>. Returns an IO action that modifies
--   the contents of that <a>Var</a>.
once :: IO a -> IO (IO a)

-- | Creates a new mailbox. Returns an action to send to the mailbox; this
--   action will return False if the mailbox is sealed, or True if the
--   message was successfully placed in the mailbox. Also returns an action
--   to retrieve from the mailbox, which returns Nothing if the mailbox is
--   sealed, or Just if there is a value to be retrieved. Also returns an
--   action to seal the mailbox.
messageBox :: IO (a -> STM Bool, STM (Maybe a), STM ())
sendBox :: TVar Bool -> TMVar a -> a -> STM Bool
recvBox :: TVar Bool -> TMVar a -> STM (Maybe a)
sealer :: TVar Bool -> STM ()
produceFromBox :: MonadIO m => STM (Maybe a) -> Producer a m ()
sendToBox :: MonadIO m => (a -> STM Bool) -> Consumer a m ()

-- | Data that is computed once, after the process has been created. After
--   computation, this data does not change.
data Console
Console :: Maybe Handle -> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO ExitCode -> Lock -> Var [IO ()] -> Console

-- | Standard input
[csIn] :: Console -> Maybe Handle

-- | Standard output
[csOut] :: Console -> Maybe Handle

-- | Standard error
[csErr] :: Console -> Maybe Handle
[csHandle] :: Console -> ProcessHandle

-- | IO action that will return the exit code. Use this rather than using
--   <a>waitForProcess</a> on the <a>csHandle</a>.
[csExitCode] :: Console -> IO ExitCode

-- | If locked, new resources cannot be created. Obtain this lock while
--   registering new releasers in <a>csReleasers</a>.
[csLock] :: Console -> Lock

-- | Each time a resource is created, register a finalizer here. These
--   finalizers are run when <a>terminateProcess</a> is run.
[csReleasers] :: Console -> Var [IO ()]

-- | Is this process still running?
--   
--   Side effects: examines the process handle to see if it has yet
--   returned a value. Does not block; should return immediately.
isStillRunning :: ProcessHandle -> IO Bool

-- | Allows you to terminate the process, as well as to obtain some
--   information about the process.
data ProcessHandle
ProcessHandle :: CreateProcess -> IO Console -> ProcessHandle
[phCreateProcess] :: ProcessHandle -> CreateProcess
[phConsole] :: ProcessHandle -> IO Console

-- | Tells you the <a>CreateProcess</a> that was originally used to create
--   the process associated with this <a>ProcessHandle</a>.
originalCreateProcess :: ProcessHandle -> CreateProcess

-- | Add a finalizer to the ProcessHandle. When the finalizers are run, all
--   exceptions are ignored, except asynchronous exceptions, which are
--   masked.
addReleaser :: ProcessHandle -> IO () -> IO ()

-- | Terminates a process. Sends the process a <tt>SIGTERM</tt>, which does
--   not absolutely guarantee that it will exit. Closes any <a>Handle</a>s
--   that were created for the process through Cliff, and terminates any
--   associated background threads that were moving data to and from the
--   process. Use this function this with <a>bracket</a> to ensure proper
--   cleanup of resources.
terminateProcess :: ProcessHandle -> IO ()

-- | Gets the exit code of the process that belongs to the
--   <a>ProcessHandle</a>. Often you can get the exit code through more
--   idiomatic <tt>pipes</tt> functions, as the various <a>Proxy</a> return
--   the <a>ExitCode</a>. Sometimes though it can be difficult to use the
--   <tt>pipes</tt> idioms to get the exit code, so this function is here.
--   
--   Side effects: may block if process has not yet exited.
waitForProcess :: ProcessHandle -> IO ExitCode

-- | Creates a new ProcessHandle.
--   
--   Side effects: Does not create the process right away; instead, creates
--   an IO action that, when run, will create the process. This IO action
--   contains another IO action that, when run, will return the process
--   exit code.
--   
--   In addition, the IO action will fork a simple thread that will
--   immediately wait for the process. In effect, this means there is
--   immediately a thread that will wait for the process to exit. Because
--   this IO action was created with <a>once</a>, that means only one
--   thread ever does the <tt>wait</tt>, which avoids a bug in
--   <a>System.Process</a>.
newProcessHandle :: Maybe NonPipe -> Maybe NonPipe -> Maybe NonPipe -> CreateProcess -> IO ProcessHandle

-- | Sends an exception using the exception handler specified in the
--   <tt>ErrSpec</tt>. Side effects: transmits the <a>Oopsie</a> to the
--   right place; the recipient of the <a>Oopsie</a> might have additional
--   side effects.
handleException :: Activity -> HandleDesc -> CmdSpec -> (Oopsie -> IO ()) -> IOException -> IO ()

-- | Close a handle. Catches any exceptions and passes them to the handler.
closeHandleNoThrow :: Handle -> HandleDesc -> CmdSpec -> (Oopsie -> IO ()) -> IO ()

-- | Runs in the background an effect, typically one that is moving data
--   from one process to another. For examples of its usage, see
--   <a>Pipes.Cliff.Examples</a>.
conveyor :: Effect (SafeT IO) a -> IO (Async a)

-- | Runs in the foreground an effect in the <a>SafeT</a> monad.
safeEffect :: Effect (SafeT IO) a -> IO a

-- | Creates a new mailbox and returns <a>Proxy</a> that stream values into
--   and out of the mailbox. Each <a>Proxy</a> 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.
--   
--   Also returns an STM action to seal the box manually.
newMailbox :: (MonadSafe mi, MonadSafe mo) => IO (Consumer a mi (), Producer a mo (), STM ())

-- | Creates a process, uses it, and terminates it when the last
--   computation ends. Don't try to use any of the process resources after
--   the last computation ends, because the process will already have been
--   terminated. For an example of its use, see
--   <a>standardOutputAndErrorBracketed</a>.
withProcess :: IO (a, ProcessHandle) -> (a -> IO b) -> IO b

-- | Runs an <a>Effect</a> in the backgroud (typically one that is moving
--   data from one process to another). If the background thread is still
--   running when the second computation ends, the background thread is
--   terminated. For an example of its use, see
--   <a>standardOutputAndErrorBracketed</a>.
withConveyor :: Effect (SafeT IO) a -> IO b -> IO b

-- | I have no idea what this should be. I'll start with a simple small
--   value and see how it works.
bufSize :: Int

-- | Initialize a handle. Returns a computation in the MonadSafe monad.
--   That computation has a registered finalizer that will close a
--   particular handle that is found in the <a>ProcessHandle</a>. As a side
--   effect, the IO action creating the <a>ProcessHandle</a> is viewed,
--   meaning that the process will launch if it hasn't already done so.
initHandle :: MonadSafe mi => HandleDesc -> (Console -> Handle) -> ProcessHandle -> (Handle -> mi a) -> mi a
consumeToHandle :: (MonadSafe mi, MonadCatch (Base mi)) => ProcessHandle -> Consumer ByteString mi ()

-- | Produce values from a process standard output. Process is started if
--   it isn't already.
produceFromHandle :: (MonadSafe mi, MonadCatch (Base mi)) => Outbound -> ProcessHandle -> Producer ByteString mi ()

-- | Given an <a>Async</a>, waits for that thread to finish processing
--   values. When it completes, wait for the process exit code.
finishProxy :: Async () -> ProcessHandle -> IO ExitCode

-- | Takes all steps necessary to get a <a>Consumer</a> for standard input:
--   
--   <ul>
--   <li>Creates a <a>Consumer</a> that will consume to the process
--   standard input. This <a>Consumer</a> registers a MonadSafe releaser
--   that will close the handle.</li>
--   <li>Creates a mailbox, with a <a>Producer</a> from the mailbox and a
--   <a>Consumer</a> to the mailbox. Each of these <a>Proxy</a> has a
--   MonadSafe releaser that will close the mailbox.</li>
--   <li>Spwans a thread to run an <a>Effect</a> that connects the
--   <a>Consumer</a> that is connected to the handle to the <a>Producer</a>
--   from the mailbox. In a typical UNIX pipeline situation (where the
--   process keeps its stdin open as long as it is getting input) this
--   <a>Effect</a> will stop running only when the mailbox is sealed.</li>
--   <li>Registers a releaser in the Panel (not in the MonadSafe
--   computation) to destroy the thread; this is in case the user
--   terminates the process.</li>
--   <li>Returns a <a>Consumer</a>. The <a>Consumer</a> consumes to the
--   mailbox. This <a>Consumer</a> returns the exit code of this process
--   (but remember that the ultimate result of the <a>Proxy</a> depends on
--   which component terminates first).</li>
--   </ul>
--   
--   Does not register in the <a>MonadSafe</a> an action to cancel the
--   background thread. Data might still be moving to the process even if
--   the <a>Proxy</a> has shut down. Let the thread terminate through
--   mailbox closure or a broken pipe.
runInputHandle :: MonadSafe mi => ProcessHandle -> Consumer ByteString mi ExitCode

-- | Takes all steps necessary to get a <a>Producer</a> for standard input.
--   Sets up a mailbox, runs a conveyor in the background. Then receives
--   streaming data, and then gets the process exit code.
runOutputHandle :: MonadSafe mi => Outbound -> ProcessHandle -> Producer ByteString mi ExitCode

-- | Create a <a>Consumer</a> for standard input.
pipeInput :: MonadSafe mi => NonPipe -> NonPipe -> CreateProcess -> IO (Consumer ByteString mi ExitCode, ProcessHandle)

-- | Create a <a>Producer</a> for standard output.
pipeOutput :: MonadSafe mo => NonPipe -> NonPipe -> CreateProcess -> IO (Producer ByteString mo ExitCode, ProcessHandle)

-- | Create a <a>Producer</a> for standard error.
pipeError :: MonadSafe me => NonPipe -> NonPipe -> CreateProcess -> IO (Producer ByteString me ExitCode, ProcessHandle)

-- | Create a <a>Consumer</a> for standard input and a <a>Producer</a> for
--   standard output.
pipeInputOutput :: (MonadSafe mi, MonadSafe mo) => NonPipe -> CreateProcess -> IO ((Consumer ByteString mi ExitCode, Producer ByteString mo ExitCode), ProcessHandle)

-- | Create a <a>Consumer</a> for standard input and a <a>Producer</a> for
--   standard error.
pipeInputError :: (MonadSafe mi, MonadSafe me) => NonPipe -> CreateProcess -> IO ((Consumer ByteString mi ExitCode, Producer ByteString me ExitCode), ProcessHandle)

-- | Create a <a>Producer</a> for standard output and a <a>Producer</a> for
--   standard error.
pipeOutputError :: (MonadSafe mo, MonadSafe me) => NonPipe -> CreateProcess -> IO ((Producer ByteString mo ExitCode, Producer ByteString me ExitCode), ProcessHandle)

-- | Create a <a>Consumer</a> for standard input, a <a>Producer</a> for
--   standard output, and a <a>Producer</a> for standard error.
pipeInputOutputError :: (MonadSafe mi, MonadSafe mo, MonadSafe me) => CreateProcess -> IO ((Consumer ByteString mi ExitCode, Producer ByteString mo ExitCode, Producer ByteString me ExitCode), ProcessHandle)
instance GHC.Show.Show Pipes.Cliff.Core.Oopsie
instance GHC.Classes.Eq Pipes.Cliff.Core.Oopsie
instance GHC.Show.Show Pipes.Cliff.Core.HandleDesc
instance GHC.Classes.Ord Pipes.Cliff.Core.HandleDesc
instance GHC.Classes.Eq Pipes.Cliff.Core.HandleDesc
instance GHC.Show.Show Pipes.Cliff.Core.Outbound
instance GHC.Classes.Ord Pipes.Cliff.Core.Outbound
instance GHC.Classes.Eq Pipes.Cliff.Core.Outbound
instance GHC.Show.Show Pipes.Cliff.Core.Activity
instance GHC.Classes.Ord Pipes.Cliff.Core.Activity
instance GHC.Classes.Eq Pipes.Cliff.Core.Activity
instance GHC.Show.Show Pipes.Cliff.Core.CmdSpec
instance GHC.Classes.Ord Pipes.Cliff.Core.CmdSpec
instance GHC.Classes.Eq Pipes.Cliff.Core.CmdSpec


-- | Spawn subprocesses and interact with them using <a>Pipes</a>
--   
--   The interface in this module deliberately resembles the interface in
--   <a>System.Process</a>. However, one consequence of this is that you
--   will not want to have unqualified names from this module and from
--   <a>System.Process</a> in scope at the same time.
--   
--   As in <a>System.Process</a>, you create a subprocess by creating a
--   <a>CreateProcess</a> record and then applying a function to that
--   record. Unlike <a>System.Process</a>, you use functions such as
--   <a>pipeInput</a> or <a>pipeInputOutput</a> to specify what streams you
--   want to use a <a>Proxy</a> for and what streams you wish to be
--   <a>Inherit</a>ed or if you want to <a>UseHandle</a>. You then send or
--   receive information using one or more <a>Proxy</a>.
--   
--   <b>Use the <tt>-threaded</tt> GHC option</b> when compiling your
--   programs or when using GHCi. Internally, this module uses
--   <a>waitForProcess</a> from the <a>System.Process</a> module. As the
--   documentation for <a>waitForProcess</a> states, you must use the
--   <tt>-threaded</tt> option to prevent every thread in the system from
--   suspending when <a>waitForProcess</a> is used. So, if your program
--   experiences deadlocks, be sure you used the <tt>-threaded</tt> option.
--   
--   This module relies on the <a>Pipes</a>, <a>Pipes.Safe</a>,
--   <a>Control.Concurrent.Async</a>, and <a>System.Process</a> modules.
--   You will want to have basic familiarity with what all of those modules
--   do before using this module.
--   
--   All communcation with subprocesses is done with strict
--   <tt>ByteString</tt>s. If you are dealing with textual data, the
--   <tt>text</tt> library has functions to convert a <tt>ByteString</tt>
--   to a <tt>Text</tt>; you will want to look at
--   <tt>Data.Text.Encoding</tt>.
--   
--   Nobody would mistake this module for a shell; nothing beats the shell
--   as a language for starting other programs, as the shell is designed
--   for that. This module allows you to perform simple streaming with
--   subprocesses without leaving the comfort of Haskell. Take a look at
--   the README.md file, which is distributed with the tarball or is
--   available at Github at
--   
--   <a>https://github.com/massysett/pipes-cliff</a>
--   
--   There you will find references to other libraries that you might find
--   more useful than this one.
--   
--   You will want to consult <a>Pipes.Cliff.Examples</a> for some examples
--   before getting started. There are some important notes in there about
--   how to run pipelines.
module Pipes.Cliff

-- | Like <a>CmdSpec</a> in <a>System.Process</a>, but also has an instance
--   for <a>Show</a>.
data CmdSpec
ShellCommand :: String -> CmdSpec
RawCommand :: FilePath -> [String] -> CmdSpec

-- | How will the subprocess get its information for this stream? A
--   <a>NonPipe</a> is used for streams that will not be assigned to a
--   <a>Proxy</a> but, instead, will be inherited from the parent or
--   directed from an existing <a>Handle</a>.
data NonPipe

-- | Use whatever stream that the parent process has.
Inherit :: NonPipe

-- | Use the given handle for input or output
UseHandle :: Handle -> NonPipe

-- | Like <a>CreateProcess</a> in <a>System.Process</a>, this gives the
--   necessary information to create a subprocess. All but one of these
--   fields is also present in <a>CreateProcess</a>, and they all have the
--   same meaning; the only field that is different is the <a>handler</a>
--   field.
data CreateProcess
CreateProcess :: CmdSpec -> Maybe FilePath -> Maybe [(String, String)] -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe GroupID -> Maybe UserID -> (Oopsie -> IO ()) -> CreateProcess

-- | Executable and arguments, or shell command
[cmdspec] :: CreateProcess -> CmdSpec

-- | A new current working directory for the subprocess; if <a>Nothing</a>,
--   use the calling process's working directory.
[cwd] :: CreateProcess -> Maybe FilePath

-- | The environment for the subprocess; if <a>Nothing</a>, use the calling
--   process's working directory.
[env] :: CreateProcess -> Maybe [(String, String)]

-- | If <a>True</a>, close all file descriptors other than the standard
--   descriptors. See the documentation for <a>close_fds</a> for details on
--   how this works in Windows.
[close_fds] :: CreateProcess -> Bool

-- | If <a>True</a>, create a new process group.
[create_group] :: CreateProcess -> Bool

-- | See <a>delegate_ctlc</a> in the <a>System.Process</a> module for
--   details.
[delegate_ctlc] :: CreateProcess -> Bool

-- | Use the windows DETACHED_PROCESS flag when creating the process; does
--   nothing on other platforms.
[detach_console] :: CreateProcess -> Bool

-- | Use the windows CREATE_NEW_CONSOLE flag when creating the process;
--   does nothing on other platforms.
[create_new_console] :: CreateProcess -> Bool

-- | Use posix setsid to start the new process in a new session; does
--   nothing on other platforms.
[new_session] :: CreateProcess -> Bool

-- | Use posix setgid to set child process's group id; does nothing on
--   other platforms.
[child_group] :: CreateProcess -> Maybe GroupID

-- | Use posix setuid to set child process's user id; does nothing on other
--   platforms.
[child_user] :: CreateProcess -> Maybe UserID

-- | Whenever an IO exception arises during the course of various IO
--   actions, the exception is caught and placed into an <a>Oopsie</a> that
--   indicates why and where the exception happened. The <a>handler</a>
--   determines what happens when an <a>Oopsie</a> comes in. See
--   <a>Oopsie</a> for details.
--   
--   The default <a>handler</a> created by <a>procSpec</a> is
--   <a>defaultHandler</a>, which will simply print the exceptions to
--   standard error. You may not want to see the exceptions at all. For
--   example, many exceptions come from broken pipes. A broken pipe might
--   be entirely normal in your circumstance. For example, if you are
--   streaming a large set of values to a pager such as <tt>less</tt> and
--   you expect that the user will often quit the pager without viewing the
--   whole result, a broken pipe will result, which will print a warning
--   message. That can be a nuisance.
--   
--   If you don't want to see the exceptions at all, just set
--   <a>handler</a> to <a>squelch</a>, which simply discards the
--   exceptions.
--   
--   Conceivably you could rig up an elaborate mechanism that puts the
--   <a>Oopsie</a>s into a <a>Pipes.Concurrent</a> mailbox or something.
--   Indeed, when using <a>defaultHandler</a> each thread will print its
--   warnings to standard error at any time. If you are using multiple
--   processes and each prints warnings at the same time, total gibberish
--   can result as the text gets mixed in. You could solve this by putting
--   the errors into a <a>Pipes.Concurrent</a> mailbox and having a single
--   thread print the errors; this sort of thing could be built into the
--   library but so far I haven't been motivated to do it.
[handler] :: CreateProcess -> Oopsie -> IO ()

-- | Create a <a>CreateProcess</a> record with default settings. The
--   default settings are:
--   
--   <ul>
--   <li>a raw command (as opposed to a shell command) is created</li>
--   <li>the current working directory is not changed from the parent
--   process</li>
--   <li>the environment is not changed from the parent process</li>
--   <li>the parent's file descriptors (other than standard input, standard
--   output, and standard error) are inherited</li>
--   <li>no new process group is created</li>
--   <li><a>delegate_ctlc</a>, <a>detach_console</a>,
--   <a>create_new_console</a>, and <a>new_session</a> are all
--   <a>False</a></li>
--   <li><a>child_group</a> and <a>child_user</a> are both
--   <a>Nothing</a></li>
--   <li><a>handler</a> is <a>defaultHandler</a></li>
--   </ul>
procSpec :: String -> [String] -> CreateProcess

-- | Do not show or do anything with exceptions; useful to use as a
--   <a>handler</a>.
--   
--   Side effects: None.
squelch :: Monad m => a -> m ()

-- | Create a <a>Consumer</a> for standard input.
pipeInput :: MonadSafe mi => NonPipe -> NonPipe -> CreateProcess -> IO (Consumer ByteString mi ExitCode, ProcessHandle)

-- | Create a <a>Producer</a> for standard output.
pipeOutput :: MonadSafe mo => NonPipe -> NonPipe -> CreateProcess -> IO (Producer ByteString mo ExitCode, ProcessHandle)

-- | Create a <a>Producer</a> for standard error.
pipeError :: MonadSafe me => NonPipe -> NonPipe -> CreateProcess -> IO (Producer ByteString me ExitCode, ProcessHandle)

-- | Create a <a>Consumer</a> for standard input and a <a>Producer</a> for
--   standard output.
pipeInputOutput :: (MonadSafe mi, MonadSafe mo) => NonPipe -> CreateProcess -> IO ((Consumer ByteString mi ExitCode, Producer ByteString mo ExitCode), ProcessHandle)

-- | Create a <a>Consumer</a> for standard input and a <a>Producer</a> for
--   standard error.
pipeInputError :: (MonadSafe mi, MonadSafe me) => NonPipe -> CreateProcess -> IO ((Consumer ByteString mi ExitCode, Producer ByteString me ExitCode), ProcessHandle)

-- | Create a <a>Producer</a> for standard output and a <a>Producer</a> for
--   standard error.
pipeOutputError :: (MonadSafe mo, MonadSafe me) => NonPipe -> CreateProcess -> IO ((Producer ByteString mo ExitCode, Producer ByteString me ExitCode), ProcessHandle)

-- | Create a <a>Consumer</a> for standard input, a <a>Producer</a> for
--   standard output, and a <a>Producer</a> for standard error.
pipeInputOutputError :: (MonadSafe mi, MonadSafe mo, MonadSafe me) => CreateProcess -> IO ((Consumer ByteString mi ExitCode, Producer ByteString mo ExitCode, Producer ByteString me ExitCode), ProcessHandle)

-- | Runs in the background an effect, typically one that is moving data
--   from one process to another. For examples of its usage, see
--   <a>Pipes.Cliff.Examples</a>.
conveyor :: Effect (SafeT IO) a -> IO (Async a)

-- | Runs in the foreground an effect in the <a>SafeT</a> monad.
safeEffect :: Effect (SafeT IO) a -> IO a

-- | Allows you to terminate the process, as well as to obtain some
--   information about the process.
data ProcessHandle

-- | Tells you the <a>CreateProcess</a> that was originally used to create
--   the process associated with this <a>ProcessHandle</a>.
originalCreateProcess :: ProcessHandle -> CreateProcess

-- | Is this process still running?
--   
--   Side effects: examines the process handle to see if it has yet
--   returned a value. Does not block; should return immediately.
isStillRunning :: ProcessHandle -> IO Bool

-- | Gets the exit code of the process that belongs to the
--   <a>ProcessHandle</a>. Often you can get the exit code through more
--   idiomatic <tt>pipes</tt> functions, as the various <a>Proxy</a> return
--   the <a>ExitCode</a>. Sometimes though it can be difficult to use the
--   <tt>pipes</tt> idioms to get the exit code, so this function is here.
--   
--   Side effects: may block if process has not yet exited.
waitForProcess :: ProcessHandle -> IO ExitCode

-- | Terminates a process. Sends the process a <tt>SIGTERM</tt>, which does
--   not absolutely guarantee that it will exit. Closes any <a>Handle</a>s
--   that were created for the process through Cliff, and terminates any
--   associated background threads that were moving data to and from the
--   process. Use this function this with <a>bracket</a> to ensure proper
--   cleanup of resources.
terminateProcess :: ProcessHandle -> IO ()

-- | Creates a process, uses it, and terminates it when the last
--   computation ends. Don't try to use any of the process resources after
--   the last computation ends, because the process will already have been
--   terminated. For an example of its use, see
--   <a>standardOutputAndErrorBracketed</a>.
withProcess :: IO (a, ProcessHandle) -> (a -> IO b) -> IO b

-- | Runs an <a>Effect</a> in the backgroud (typically one that is moving
--   data from one process to another). If the background thread is still
--   running when the second computation ends, the background thread is
--   terminated. For an example of its use, see
--   <a>standardOutputAndErrorBracketed</a>.
withConveyor :: Effect (SafeT IO) a -> IO b -> IO b

-- | When dealing with a <a>Handle</a>, errors can occur when reading from,
--   writing to, or closing the handle.
data Activity
Reading :: Activity
Writing :: Activity
Closing :: Activity

-- | The two kinds of outbound handles.
data Outbound
Output :: Outbound
Error :: Outbound

-- | Describes a handle. From the perspective of the subprocess; for
--   example, <a>Input</a> means that this handle is connected to the
--   process's standard input.
data HandleDesc
Input :: HandleDesc
Outbound :: Outbound -> HandleDesc

-- | Describes all IO exceptions. The <a>Oopsie</a> contains the
--   <a>IOException</a> itself, along with the <a>CmdSpec</a> that was
--   running when the exception occurred.
--   
--   The exceptions that are caught and placed into an <a>Oopsie</a> may
--   arise from reading data from or writing data to a <a>Handle</a>. In
--   these errors, the associated <a>Producer</a> or <a>Consumer</a> will
--   terminate (which may trigger various cleanup actions in the
--   <a>MonadSafe</a> computation) but the exception itself is not
--   re-thrown; rather, it is passed to the <a>handler</a>. Similarly, an
--   exception may occur while closing a handle; these exceptions are
--   caught, not rethrown, and are passed to the <a>handler</a>. 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
--   <a>handler</a>.
--   
--   If an exception arises when creating a process--such as a command not
--   being found--the exception is <i>not</i> caught, handled, or passed to
--   the <a>handler</a>. In addition, no exceptions are caught if they
--   originated during a <a>waitForProcess</a>. (I can't conceive of how
--   any synchronous exceptions could arise from <a>waitForProcess</a>, but
--   if they do, Cliff does not handle them.) Also, an <a>Oopsie</a> is
--   created only for an <a>IOException</a>; no other exceptions of any
--   kind are caught or handled. However, exceptions of any kind will still
--   trigger appropriate cleanup actions in the <a>MonadSafe</a>
--   computation.
data Oopsie
Oopsie :: Activity -> HandleDesc -> CmdSpec -> IOException -> Oopsie


-- | Examples using <a>Pipes.Cliff</a>. You will want to look at the source
--   code itself; viewing just the Haddocks will not help you much. You can
--   view the source using Haddock if you used <tt>--hyperlink-source</tt>
--   when building the library or if you are viewing this on Hackage; look
--   for the <tt>Source</tt> link. Or, you can find the source at
--   
--   
--   <a>https://github.com/massysett/pipes-cliff/blob/master/lib/Pipes/Cliff/Examples.hs</a>
--   
--   <b>Be sure to use the <tt>-threaded</tt> option</b> when compiling
--   code that uses <a>Pipes.Cliff</a>, including this code; see the
--   warning in <a>Pipes.Cliff</a> for more details.
--   
--   Notice throughout how pipelines that move data from one process to
--   another typically are run in the background using <a>conveyor</a>,
--   which spawns a thread. You have to make sure all these threads are
--   running concurrently so that data flows through your pipeline (a shell
--   does this sort of thing for you.)
module Pipes.Cliff.Examples

-- | Produces a stream of <a>ByteString</a>, where each <a>ByteString</a>
--   is a shown integer. This is an infinite stream. In the examples below
--   we'll send this infinite stream off into a Unix pipeline, a feat that
--   would be very difficult and clumsy without a framework like
--   <tt>pipes</tt>.
produceNumbers :: Monad m => Producer ByteString m r

-- | Streams an infinite list of numbers to <tt>less</tt>. Shows off how
--   you can use <a>Pipes.Cliff</a> even for non-finite <a>Producer</a>s.
--   Don't try to go to the end of the input in <tt>less</tt>, though. When
--   you quit <tt>less</tt>, you will get broken pipe warnings printed to
--   standard error. This is normal. To suppress them, see the
--   <a>handler</a> option.
numsToLess :: IO ExitCode

-- | Streams an infinite list of numbers to <tt>tr</tt> and then to
--   <tt>less</tt>. Perfectly useless, but shows how to build pipelines.
--   Also squlches warning messages using the <a>handler</a> option.
--   
--   Note that, consistent with usual <tt>pipes</tt> usage, the value of
--   <tt>code1</tt> and <tt>code2</tt> is not necessarily the last exit
--   code in the pipeline. Rather, it is the exit code of the process that
--   terminated first. Use <a>waitForProcess</a> if you need to determine
--   the exit value of a particular process. It's also possible to use a
--   bit of <a>fmap</a> to see which process in a pipeline did terminate
--   first; for an example of that, search the <a>Pipes.Tutorial</a> module
--   for <tt>echo3.hs</tt>.
alphaNumbers :: IO (ExitCode, ExitCode)

-- | Produces an infinite stream of numbers, sends it to <tt>tr</tt> for
--   some mangling, and then to <tt>sh</tt>, which will copy each line both
--   to standard output and to standard error. From <tt>sh</tt>, standard
--   output is then sent off to <tt>less</tt>, and standard error is sent
--   to a separate thread which will collect the results and return them.
--   
--   This example shows you how to write a pipeline that deals with both
--   standard output and standard error.
--   
--   It's also interesting to note here that because of the buffering that
--   happens in various places throughout the pipeline, and because less
--   itself also buffers its input, the output you will see from the
--   <tt>sh</tt> process's standard error will be much longer than the
--   output the user actually viewed in <tt>less</tt>.
standardOutputAndError :: IO ByteString

-- | Like <a>alphaNumbers</a> but just sends a limited number of numbers to
--   <tt>cat</tt>. A useful test to make sure that pipelines shut down
--   automatically.
limitedAlphaNumbers :: IO ExitCode

-- | Produces a finite list of numbers, sends it to <tt>tr</tt> for some
--   mangling, and then puts the results into a <a>ByteString</a> for
--   further processing. This example shows how you can use this library to
--   place the results of a pipeline into a simple strict data type.
alphaNumbersByteString :: IO ByteString

-- | So far, all examples have ignored the issue of exception safety.
--   Here's an example that properly uses <tt>bracket</tt> to make sure
--   that all resource allocations are cleaned up if there is an exception.
--   Otherwise, it's identical to <a>standardOutputAndError</a>. You can
--   put some <tt>do</tt> notation sugar in here and eliminate all the
--   hanging lambdas and <a>$</a>s by using the <tt>ContT</tt> monad from
--   <tt>transformers</tt> (I did not write the example that way to avoid
--   incurring a direct dependency on <tt>transformers</tt>).
standardOutputAndErrorBracketed :: IO ByteString
