diff --git a/static/typed-process/System-Process-Typed.html b/static/typed-process/System-Process-Typed.html new file mode 100644 index 0000000..87af7ad --- /dev/null +++ b/static/typed-process/System-Process-Typed.html @@ -0,0 +1,63 @@ +System.Process.Typed

typed-process-0.1.0.0: Alternative API for processes, featuring more type safety

Safe HaskellNone
LanguageHaskell2010

System.Process.Typed

Contents

Description

Please see the README.md file for examples of using this API.

Synopsis

Types

data ProcessConfig stdin stdout stderr Source #

An abstract configuration for a process, which can then be + launched into an actual running Process. Takes three type + parameters, providing the types of standard input, standard output, + and standard error, respectively.

There are three ways to construct a value of this type:

  • With the proc smart constructor, which takes a command name and + a list of arguments.
  • With the shell smart constructor, which takes a shell string
  • With the IsString instance via OverloadedStrings. If you + provide it a string with no spaces (e.g., "date"), it will + treat it as a raw command with no arguments (e.g., proc "date" + []). If it has spaces, it will use shell.

In all cases, the default for all three streams is to inherit the + streams from the parent process. For other settings, see the + setters below for default values.

Since: 0.1.0.0

Instances

((~) * stdin (), (~) * stdout (), (~) * stderr ()) => IsString (ProcessConfig stdin stdout stderr) Source # 

Methods

fromString :: String -> ProcessConfig stdin stdout stderr #

data StreamSpec streamType a Source #

A specification for how to create one of the three standard child + streams. See examples below.

Since: 0.1.0.0

Instances

Functor (StreamSpec streamType) Source # 

Methods

fmap :: (a -> b) -> StreamSpec streamType a -> StreamSpec streamType b #

(<$) :: a -> StreamSpec streamType b -> StreamSpec streamType a #

((~) StreamType streamType STInput, (~) * res ()) => IsString (StreamSpec streamType res) Source #

This instance uses byteStringInput to convert a raw string into + a stream of input for a child process.

Since: 0.1.0.0

Methods

fromString :: String -> StreamSpec streamType res #

data StreamType Source #

Whether a stream is an input stream or output stream. Note that + this is from the perspective of the child process, so that a + child's standard input stream is an STInput, even though the + parent process will be writing to it.

Since: 0.1.0.0

Constructors

STInput 
STOutput 

data Process stdin stdout stderr Source #

A running process. The three type parameters provide the type of + the standard input, standard output, and standard error streams.

Since: 0.1.0.0

ProcessConfig

Smart constructors

proc :: FilePath -> [String] -> ProcessConfig () () () Source #

Create a ProcessConfig from the given command and arguments.

Since: 0.1.0.0

shell :: String -> ProcessConfig () () () Source #

Create a ProcessConfig from the given shell command.

Since: 0.1.0.0

Setters

setStdin :: StreamSpec STInput stdin -> ProcessConfig stdin0 stdout stderr -> ProcessConfig stdin stdout stderr Source #

Set the child's standard input stream to the given StreamSpec.

Default: inherit

Since: 0.1.0.0

setStdout :: StreamSpec STOutput stdout -> ProcessConfig stdin stdout0 stderr -> ProcessConfig stdin stdout stderr Source #

Set the child's standard output stream to the given StreamSpec.

Default: inherit

Since: 0.1.0.0

setStderr :: StreamSpec STOutput stderr -> ProcessConfig stdin stdout stderr0 -> ProcessConfig stdin stdout stderr Source #

Set the child's standard error stream to the given StreamSpec.

Default: inherit

Since: 0.1.0.0

setWorkingDir :: FilePath -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr Source #

Set the working directory of the child process.

Default: current process's working directory.

Since: 0.1.0.0

setEnv :: [(String, String)] -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr Source #

Set the environment variables of the child process.

Default: current process's environment.

Since: 0.1.0.0

setCloseFds :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr Source #

Should we close all file descriptors besides stdin, stdout, and + stderr? See close_fds for more information.

Default: False

Since: 0.1.0.0

setCreateGroup :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr Source #

Should we create a new process group?

Default: False

Since: 0.1.0.0

setDelegateCtlc :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr Source #

Delegate handling of Ctrl-C to the child. For more information, + see delegate_ctlc.

Default: False

Since: 0.1.0.0

setDetachConsole :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr Source #

Detach console on Windows, see detach_console.

Default: False

Since: 0.1.0.0

setCreateNewConsole :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr Source #

Create new console on Windows, see create_new_console.

Default: False

Since: 0.1.0.0

setNewSession :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr Source #

Set a new session with the POSIX setsid syscall, does nothing + on non-POSIX. See new_session.

Default: False

Since: 0.1.0.0

setChildGroup :: GroupID -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr Source #

Set the child process's group ID with the POSIX setgid syscall, + does nothing on non-POSIX. See child_group.

Default: False

Since: 0.1.0.0

setChildUser :: UserID -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr Source #

Set the child process's user ID with the POSIX setuid syscall, + does nothing on non-POSIX. See child_user.

Default: False

Since: 0.1.0.0

setCheckExitCode :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr Source #

Should we throw an exception when the process exits with a + non-success code?

If set to True, then when stopProcess is called - either + directly or via withProcess or other wrappers - the processes + exit code will be checked. Any exit code besides ExitSuccess will + result in an ExitCodeException being thrown.

Default: False

Since: 0.1.0.0

Stream specs

mkStreamSpec :: StdStream -> (Maybe Handle -> IO (a, IO ())) -> StreamSpec streamType a Source #

Create a new StreamSpec from the given StdStream and a + helper function. This function:

  • Takes as input the raw Maybe Handle returned by the + createProcess function. This will be determined by the + StdStream argument.
  • Returns the actual stream value a, as well as a cleanup
  • function to be run when calling stopProcess.

Since: 0.1.0.0

inherit :: StreamSpec anyStreamType () Source #

A stream spec which simply inherits the stream of the parent + process.

Since: 0.1.0.0

closed :: StreamSpec anyStreamType () Source #

A stream spec which will close the stream for the child process.

Since: 0.1.0.0

byteStringInput :: ByteString -> StreamSpec STInput () Source #

An input stream spec which sets the input to the given + ByteString. A separate thread will be forked to write the + contents to the child process.

Since: 0.1.0.0

byteStringOutput :: StreamSpec STOutput (STM (Either ByteStringOutputException ByteString)) Source #

Capture the output of a process in a ByteString.

This function will fork a separate thread to consume all input from + the process, and will only make the results available when the + underlying Handle is closed. As this is provided as an STM + action, you can either check if the result is available, or block + until it's ready.

In the event of any exception occurring when reading from the + Handle, the result of this function will be a Left value + containing a ByteStringOutputException.

Since: 0.1.0.0

createPipe :: StreamSpec anyStreamType Handle Source #

Create a new pipe between this process and the child, and return + a Handle to communicate with the child.

Since: 0.1.0.0

useHandleOpen :: Handle -> StreamSpec anyStreamType () Source #

Use the provided Handle for the child process, and when the + process exits, do not close it. This is useful if, for example, + you want to have multiple processes write to the same log file + sequentially.

Since: 0.1.0.0

useHandleClose :: Handle -> StreamSpec anyStreamType () Source #

Use the provided Handle for the child process, and when the + process exits, close it. If you have no reason to keep the Handle + open, you should use this over useHandleOpen.

Since: 0.1.0.0

sink :: MonadIO m => StreamSpec STInput (ConduitM ByteString o m ()) Source #

Provide input to a process by writing to a conduit.

Since: 0.1.0.0

source :: MonadIO m => StreamSpec STOutput (ConduitM i ByteString m ()) Source #

Read output from a process by read from a conduit.

Since: 0.1.0.0

Launch a process

startProcess :: MonadIO m => ProcessConfig stdin stdout stderr -> m (Process stdin stdout stderr) Source #

Launch a process based on the given ProcessConfig. You should + ensure that you close stopProcess on the result. It's usually + better to use one of the functions in this module which ensures + stopProcess is called, such as withProcess.

Since: 0.1.0.0

stopProcess :: MonadIO m => Process stdin stdout stderr -> m () Source #

Close a process and release any resources acquired. This will + ensure terminateProcess is called, wait for the process to + actually exit, and then close out resources allocated for the + streams. In the event of any cleanup exceptions being thrown, or if + a non-success exit code was received and setCheckExitCode was + used, this will throw an exception.

Since: 0.1.0.0

withProcess :: (MonadIO m, MonadMask m) => ProcessConfig stdin stdout stderr -> (Process stdin stdout stderr -> m a) -> m a Source #

Use the bracket pattern to call startProcess and ensure + stopProcess is called.

Since: 0.1.0.0

readProcess :: MonadIO m => ProcessConfig stdin stdoutIgnored stderrIgnored -> m (ExitCode, ByteString, ByteString) Source #

Run a process, capture its standard output and error as a + ByteString, wait for it to complete, and then return its exit + code, output, and error.

Note that any previously used setStdout or setStderr will be + overridden.

Since: 0.1.0.0

runProcess :: MonadIO m => ProcessConfig stdin stdout stderr -> m ExitCode Source #

Run the given process, wait for it to exit, and returns its + ExitCode.

Since: 0.1.0.0

runProcess_ :: MonadIO m => ProcessConfig stdin stdout stderr -> m () Source #

Same as runProcess, but ignores the ExitCode.

Since: 0.1.0.0

Interact with a process

Process exit code

waitExitCode :: MonadIO m => Process stdin stdout stderr -> m ExitCode Source #

Wait for the process to exit and then return its ExitCode.

Since: 0.1.0.0

waitExitCodeSTM :: Process stdin stdout stderr -> STM ExitCode Source #

Same as waitExitCode, but in STM.

Since: 0.1.0.0

checkExitCode :: MonadIO m => Process stdin stdout stderr -> m (Maybe ExitCode) Source #

Check if a process has exited and, if so, return its ExitCode.

Since: 0.1.0.0

checkExitCodeSTM :: Process stdin stdout stderr -> STM (Maybe ExitCode) Source #

Same as checkExitCode, but in STM.

Since: 0.1.0.0

Process streams

getStdin :: Process stdin stdout stderr -> stdin Source #

Get the child's standard input stream value.

Since: 0.1.0.0

getStdout :: Process stdin stdout stderr -> stdout Source #

Get the child's standard output stream value.

Since: 0.1.0.0

getStderr :: Process stdin stdout stderr -> stderr Source #

Get the child's standard error stream value.

Since: 0.1.0.0

Exceptions

data ExitCodeException Source #

Exit code generated by stopProcess when setCheckExitCode is + True and a process exits with a non-success code. Contains the + non-success code, and if any other exceptions occur during cleanup, + that exception.

Since: 0.1.0.0

\ No newline at end of file diff --git a/static/typed-process/doc-index.html b/static/typed-process/doc-index.html new file mode 100644 index 0000000..388b702 --- /dev/null +++ b/static/typed-process/doc-index.html @@ -0,0 +1,4 @@ +typed-process-0.1.0.0: Alternative API for processes, featuring more type safety (Index)

typed-process-0.1.0.0: Alternative API for processes, featuring more type safety

Index

byteStringInputSystem.Process.Typed
byteStringOutputSystem.Process.Typed
ByteStringOutputException 
1 (Type/Class)System.Process.Typed
2 (Data Constructor)System.Process.Typed
checkExitCodeSystem.Process.Typed
checkExitCodeSTMSystem.Process.Typed
closedSystem.Process.Typed
createPipeSystem.Process.Typed
ExitCodeException 
1 (Type/Class)System.Process.Typed
2 (Data Constructor)System.Process.Typed
getStderrSystem.Process.Typed
getStdinSystem.Process.Typed
getStdoutSystem.Process.Typed
inheritSystem.Process.Typed
mkStreamSpecSystem.Process.Typed
procSystem.Process.Typed
ProcessSystem.Process.Typed
ProcessConfigSystem.Process.Typed
readProcessSystem.Process.Typed
runProcessSystem.Process.Typed
runProcess_System.Process.Typed
setCheckExitCodeSystem.Process.Typed
setChildGroupSystem.Process.Typed
setChildUserSystem.Process.Typed
setCloseFdsSystem.Process.Typed
setCreateGroupSystem.Process.Typed
setCreateNewConsoleSystem.Process.Typed
setDelegateCtlcSystem.Process.Typed
setDetachConsoleSystem.Process.Typed
setEnvSystem.Process.Typed
setNewSessionSystem.Process.Typed
setStderrSystem.Process.Typed
setStdinSystem.Process.Typed
setStdoutSystem.Process.Typed
setWorkingDirSystem.Process.Typed
shellSystem.Process.Typed
sinkSystem.Process.Typed
sourceSystem.Process.Typed
startProcessSystem.Process.Typed
STInputSystem.Process.Typed
stopProcessSystem.Process.Typed
STOutputSystem.Process.Typed
StreamSpecSystem.Process.Typed
StreamTypeSystem.Process.Typed
useHandleCloseSystem.Process.Typed
useHandleOpenSystem.Process.Typed
waitExitCodeSystem.Process.Typed
waitExitCodeSTMSystem.Process.Typed
withProcessSystem.Process.Typed
\ No newline at end of file diff --git a/static/typed-process/frames.html b/static/typed-process/frames.html new file mode 100644 index 0000000..e86edb6 --- /dev/null +++ b/static/typed-process/frames.html @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/static/typed-process/haddock-util.js b/static/typed-process/haddock-util.js new file mode 100644 index 0000000..fc7743f --- /dev/null +++ b/static/typed-process/haddock-util.js @@ -0,0 +1,344 @@ +// Haddock JavaScript utilities + +var rspace = /\s\s+/g, + rtrim = /^\s+|\s+$/g; + +function spaced(s) { return (" " + s + " ").replace(rspace, " "); } +function trim(s) { return s.replace(rtrim, ""); } + +function hasClass(elem, value) { + var className = spaced(elem.className || ""); + return className.indexOf( " " + value + " " ) >= 0; +} + +function addClass(elem, value) { + var className = spaced(elem.className || ""); + if ( className.indexOf( " " + value + " " ) < 0 ) { + elem.className = trim(className + " " + value); + } +} + +function removeClass(elem, value) { + var className = spaced(elem.className || ""); + className = className.replace(" " + value + " ", " "); + elem.className = trim(className); +} + +function toggleClass(elem, valueOn, valueOff, bool) { + if (bool == null) { bool = ! hasClass(elem, valueOn); } + if (bool) { + removeClass(elem, valueOff); + addClass(elem, valueOn); + } + else { + removeClass(elem, valueOn); + addClass(elem, valueOff); + } + return bool; +} + + +function makeClassToggle(valueOn, valueOff) +{ + return function(elem, bool) { + return toggleClass(elem, valueOn, valueOff, bool); + } +} + +toggleShow = makeClassToggle("show", "hide"); +toggleCollapser = makeClassToggle("collapser", "expander"); + +function toggleSection(id) +{ + var b = toggleShow(document.getElementById("section." + id)); + toggleCollapser(document.getElementById("control." + id), b); + rememberCollapsed(id, b); + return b; +} + +var collapsed = {}; +function rememberCollapsed(id, b) +{ + if(b) + delete collapsed[id] + else + collapsed[id] = null; + + var sections = []; + for(var i in collapsed) + { + if(collapsed.hasOwnProperty(i)) + sections.push(i); + } + // cookie specific to this page; don't use setCookie which sets path=/ + document.cookie = "collapsed=" + escape(sections.join('+')); +} + +function restoreCollapsed() +{ + var cookie = getCookie("collapsed"); + if(!cookie) + return; + + var ids = cookie.split('+'); + for(var i in ids) + { + if(document.getElementById("section." + ids[i])) + toggleSection(ids[i]); + } +} + +function setCookie(name, value) { + document.cookie = name + "=" + escape(value) + ";path=/;"; +} + +function clearCookie(name) { + document.cookie = name + "=;path=/;expires=Thu, 01-Jan-1970 00:00:01 GMT;"; +} + +function getCookie(name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for(var i=0;i < ca.length;i++) { + var c = ca[i]; + while (c.charAt(0)==' ') c = c.substring(1,c.length); + if (c.indexOf(nameEQ) == 0) { + return unescape(c.substring(nameEQ.length,c.length)); + } + } + return null; +} + + + +var max_results = 75; // 50 is not enough to search for map in the base libraries +var shown_range = null; +var last_search = null; + +function quick_search() +{ + perform_search(false); +} + +function full_search() +{ + perform_search(true); +} + + +function perform_search(full) +{ + var text = document.getElementById("searchbox").value.toLowerCase(); + if (text == last_search && !full) return; + last_search = text; + + var table = document.getElementById("indexlist"); + var status = document.getElementById("searchmsg"); + var children = table.firstChild.childNodes; + + // first figure out the first node with the prefix + var first = bisect(-1); + var last = (first == -1 ? -1 : bisect(1)); + + if (first == -1) + { + table.className = ""; + status.innerHTML = "No results found, displaying all"; + } + else if (first == 0 && last == children.length - 1) + { + table.className = ""; + status.innerHTML = ""; + } + else if (last - first >= max_results && !full) + { + table.className = ""; + status.innerHTML = "More than " + max_results + ", press Search to display"; + } + else + { + // decide what you need to clear/show + if (shown_range) + setclass(shown_range[0], shown_range[1], "indexrow"); + setclass(first, last, "indexshow"); + shown_range = [first, last]; + table.className = "indexsearch"; + status.innerHTML = ""; + } + + + function setclass(first, last, status) + { + for (var i = first; i <= last; i++) + { + children[i].className = status; + } + } + + + // do a binary search, treating 0 as ... + // return either -1 (no 0's found) or location of most far match + function bisect(dir) + { + var first = 0, finish = children.length - 1; + var mid, success = false; + + while (finish - first > 3) + { + mid = Math.floor((finish + first) / 2); + + var i = checkitem(mid); + if (i == 0) i = dir; + if (i == -1) + finish = mid; + else + first = mid; + } + var a = (dir == 1 ? first : finish); + var b = (dir == 1 ? finish : first); + for (var i = b; i != a - dir; i -= dir) + { + if (checkitem(i) == 0) return i; + } + return -1; + } + + + // from an index, decide what the result is + // 0 = match, -1 is lower, 1 is higher + function checkitem(i) + { + var s = getitem(i).toLowerCase().substr(0, text.length); + if (s == text) return 0; + else return (s > text ? -1 : 1); + } + + + // from an index, get its string + // this abstracts over alternates + function getitem(i) + { + for ( ; i >= 0; i--) + { + var s = children[i].firstChild.firstChild.data; + if (s.indexOf(' ') == -1) + return s; + } + return ""; // should never be reached + } +} + +function setSynopsis(filename) { + if (parent.window.synopsis && parent.window.synopsis.location) { + if (parent.window.synopsis.location.replace) { + // In Firefox this avoids adding the change to the history. + parent.window.synopsis.location.replace(filename); + } else { + parent.window.synopsis.location = filename; + } + } +} + +function addMenuItem(html) { + var menu = document.getElementById("page-menu"); + if (menu) { + var btn = menu.firstChild.cloneNode(false); + btn.innerHTML = html; + menu.appendChild(btn); + } +} + +function adjustForFrames() { + var bodyCls; + + if (parent.location.href == window.location.href) { + // not in frames, so add Frames button + addMenuItem("Frames"); + bodyCls = "no-frame"; + } + else { + bodyCls = "in-frame"; + } + addClass(document.body, bodyCls); +} + +function reframe() { + setCookie("haddock-reframe", document.URL); + window.location = "frames.html"; +} + +function postReframe() { + var s = getCookie("haddock-reframe"); + if (s) { + parent.window.main.location = s; + clearCookie("haddock-reframe"); + } +} + +function styles() { + var i, a, es = document.getElementsByTagName("link"), rs = []; + for (i = 0; a = es[i]; i++) { + if(a.rel.indexOf("style") != -1 && a.title) { + rs.push(a); + } + } + return rs; +} + +function addStyleMenu() { + var as = styles(); + var i, a, btns = ""; + for(i=0; a = as[i]; i++) { + btns += "
  • " + + a.title + "
  • " + } + if (as.length > 1) { + var h = "
    " + + "Style ▾" + + "" + + "
    "; + addMenuItem(h); + } +} + +function setActiveStyleSheet(title) { + var as = styles(); + var i, a, found; + for(i=0; a = as[i]; i++) { + a.disabled = true; + // need to do this always, some browsers are edge triggered + if(a.title == title) { + found = a; + } + } + if (found) { + found.disabled = false; + setCookie("haddock-style", title); + } + else { + as[0].disabled = false; + clearCookie("haddock-style"); + } + styleMenu(false); +} + +function resetStyle() { + var s = getCookie("haddock-style"); + if (s) setActiveStyleSheet(s); +} + + +function styleMenu(show) { + var m = document.getElementById('style-menu'); + if (m) toggleShow(m, show); +} + + +function pageLoad() { + addStyleMenu(); + adjustForFrames(); + resetStyle(); + restoreCollapsed(); +} + diff --git a/static/typed-process/hslogo-16.png b/static/typed-process/hslogo-16.png new file mode 100644 index 0000000..0ff8579 Binary files /dev/null and b/static/typed-process/hslogo-16.png differ diff --git a/static/typed-process/index-frames.html b/static/typed-process/index-frames.html new file mode 100644 index 0000000..4dd5d6c --- /dev/null +++ b/static/typed-process/index-frames.html @@ -0,0 +1,4 @@ +typed-process-0.1.0.0: Alternative API for processes, featuring more type safety

    Modules

    \ No newline at end of file diff --git a/static/typed-process/index.html b/static/typed-process/index.html new file mode 100644 index 0000000..cdfed62 --- /dev/null +++ b/static/typed-process/index.html @@ -0,0 +1,4 @@ +typed-process-0.1.0.0: Alternative API for processes, featuring more type safety

    typed-process-0.1.0.0: Alternative API for processes, featuring more type safety

    typed-process-0.1.0.0: Alternative API for processes, featuring more type safety

    Please see README.md

    Modules

    \ No newline at end of file diff --git a/static/typed-process/mini_System-Process-Typed.html b/static/typed-process/mini_System-Process-Typed.html new file mode 100644 index 0000000..a1ec3f8 --- /dev/null +++ b/static/typed-process/mini_System-Process-Typed.html @@ -0,0 +1,4 @@ +System.Process.Typed

    System.Process.Typed

    Types

    data ProcessConfig stdin stdout stderr

    data StreamSpec streamType a

    data StreamType

    data Process stdin stdout stderr

    ProcessConfig

    Smart constructors

    proc

    shell

    Setters

    setStdin

    setStdout

    setStderr

    setWorkingDir

    setEnv

    setCloseFds

    setCreateGroup

    setDelegateCtlc

    setDetachConsole

    setCreateNewConsole

    setNewSession

    setChildGroup

    setChildUser

    setCheckExitCode

    Stream specs

    mkStreamSpec

    inherit

    closed

    byteStringInput

    byteStringOutput

    createPipe

    useHandleOpen

    useHandleClose

    sink

    source

    Launch a process

    startProcess

    stopProcess

    withProcess

    readProcess

    runProcess

    runProcess_

    Interact with a process

    Process exit code

    waitExitCode

    waitExitCodeSTM

    checkExitCode

    checkExitCodeSTM

    Process streams

    getStdin

    getStdout

    getStderr

    Exceptions

    data ExitCodeException

    data ByteStringOutputException

    \ No newline at end of file diff --git a/static/typed-process/minus.gif b/static/typed-process/minus.gif new file mode 100644 index 0000000..1deac2f Binary files /dev/null and b/static/typed-process/minus.gif differ diff --git a/static/typed-process/ocean.css b/static/typed-process/ocean.css new file mode 100644 index 0000000..3ebb14d --- /dev/null +++ b/static/typed-process/ocean.css @@ -0,0 +1,610 @@ +/* @group Fundamentals */ + +* { margin: 0; padding: 0 } + +/* Is this portable? */ +html { + background-color: white; + width: 100%; + height: 100%; +} + +body { + background: white; + color: black; + text-align: left; + min-height: 100%; + position: relative; +} + +p { + margin: 0.8em 0; +} + +ul, ol { + margin: 0.8em 0 0.8em 2em; +} + +dl { + margin: 0.8em 0; +} + +dt { + font-weight: bold; +} +dd { + margin-left: 2em; +} + +a { text-decoration: none; } +a[href]:link { color: rgb(196,69,29); } +a[href]:visited { color: rgb(171,105,84); } +a[href]:hover { text-decoration:underline; } + +a[href].def:link, a[href].def:visited { color: black; } +a[href].def:hover { color: rgb(78, 98, 114); } + +/* @end */ + +/* @group Fonts & Sizes */ + +/* Basic technique & IE workarounds from YUI 3 + For reasons, see: + http://yui.yahooapis.com/3.1.1/build/cssfonts/fonts.css + */ + +body { + font:13px/1.4 sans-serif; + *font-size:small; /* for IE */ + *font:x-small; /* for IE in quirks mode */ +} + +h1 { font-size: 146.5%; /* 19pt */ } +h2 { font-size: 131%; /* 17pt */ } +h3 { font-size: 116%; /* 15pt */ } +h4 { font-size: 100%; /* 13pt */ } +h5 { font-size: 100%; /* 13pt */ } + +select, input, button, textarea { + font:99% sans-serif; +} + +table { + font-size:inherit; + font:100%; +} + +pre, code, kbd, samp, tt, .src { + font-family:monospace; + *font-size:108%; + line-height: 124%; +} + +.links, .link { + font-size: 85%; /* 11pt */ +} + +#module-header .caption { + font-size: 182%; /* 24pt */ +} + +.info { + font-size: 85%; /* 11pt */ +} + +#table-of-contents, #synopsis { + /* font-size: 85%; /* 11pt */ +} + + +/* @end */ + +/* @group Common */ + +.caption, h1, h2, h3, h4, h5, h6 { + font-weight: bold; + color: rgb(78,98,114); + margin: 0.8em 0 0.4em; +} + +* + h1, * + h2, * + h3, * + h4, * + h5, * + h6 { + margin-top: 2em; +} + +h1 + h2, h2 + h3, h3 + h4, h4 + h5, h5 + h6 { + margin-top: inherit; +} + +ul.links { + list-style: none; + text-align: left; + float: right; + display: inline-table; + margin: 0 0 0 1em; +} + +ul.links li { + display: inline; + border-left: 1px solid #d5d5d5; + white-space: nowrap; + padding: 0; +} + +ul.links li a { + padding: 0.2em 0.5em; +} + +.hide { display: none; } +.show { display: inherit; } +.clear { clear: both; } + +.collapser { + background-image: url(minus.gif); + background-repeat: no-repeat; +} +.expander { + background-image: url(plus.gif); + background-repeat: no-repeat; +} +.collapser, .expander { + padding-left: 14px; + margin-left: -14px; + cursor: pointer; +} +p.caption.collapser, +p.caption.expander { + background-position: 0 0.4em; +} + +.instance.collapser, .instance.expander { + margin-left: 0px; + background-position: left center; + min-width: 9px; + min-height: 9px; +} + + +pre { + padding: 0.25em; + margin: 0.8em 0; + background: rgb(229,237,244); + overflow: auto; + border-bottom: 0.25em solid white; + /* white border adds some space below the box to compensate + for visual extra space that paragraphs have between baseline + and the bounding box */ +} + +.src { + background: #f0f0f0; + padding: 0.2em 0.5em; +} + +.keyword { font-weight: normal; } +.def { font-weight: bold; } + +@media print { + #footer { display: none; } +} + +/* @end */ + +/* @group Page Structure */ + +#content { + margin: 0 auto; + padding: 0 2em 6em; +} + +#package-header { + background: rgb(41,56,69); + border-top: 5px solid rgb(78,98,114); + color: #ddd; + padding: 0.2em; + position: relative; + text-align: left; +} + +#package-header .caption { + background: url(hslogo-16.png) no-repeat 0em; + color: white; + margin: 0 2em; + font-weight: normal; + font-style: normal; + padding-left: 2em; +} + +#package-header a:link, #package-header a:visited { color: white; } +#package-header a:hover { background: rgb(78,98,114); } + +#module-header .caption { + color: rgb(78,98,114); + font-weight: bold; + border-bottom: 1px solid #ddd; +} + +table.info { + float: right; + padding: 0.5em 1em; + border: 1px solid #ddd; + color: rgb(78,98,114); + background-color: #fff; + max-width: 40%; + border-spacing: 0; + position: relative; + top: -0.5em; + margin: 0 0 0 2em; +} + +.info th { + padding: 0 1em 0 0; +} + +div#style-menu-holder { + position: relative; + z-index: 2; + display: inline; +} + +#style-menu { + position: absolute; + z-index: 1; + overflow: visible; + background: #374c5e; + margin: 0; + text-align: center; + right: 0; + padding: 0; + top: 1.25em; +} + +#style-menu li { + display: list-item; + border-style: none; + margin: 0; + padding: 0; + color: #000; + list-style-type: none; +} + +#style-menu li + li { + border-top: 1px solid #919191; +} + +#style-menu a { + width: 6em; + padding: 3px; + display: block; +} + +#footer { + background: #ddd; + border-top: 1px solid #aaa; + padding: 0.5em 0; + color: #666; + text-align: center; + position: absolute; + bottom: 0; + width: 100%; + height: 3em; +} + +/* @end */ + +/* @group Front Matter */ + +#table-of-contents { + float: right; + clear: right; + background: #faf9dc; + border: 1px solid #d8d7ad; + padding: 0.5em 1em; + max-width: 20em; + margin: 0.5em 0 1em 1em; +} + +#table-of-contents .caption { + text-align: center; + margin: 0; +} + +#table-of-contents ul { + list-style: none; + margin: 0; +} + +#table-of-contents ul ul { + margin-left: 2em; +} + +#description .caption { + display: none; +} + +#synopsis { + display: none; +} + +.no-frame #synopsis { + display: block; + position: fixed; + right: 0; + height: 80%; + top: 10%; + padding: 0; + max-width: 75%; +} + +#synopsis .caption { + float: left; + width: 29px; + color: rgba(255,255,255,0); + height: 110px; + margin: 0; + font-size: 1px; + padding: 0; +} + +#synopsis p.caption.collapser { + background: url(synopsis.png) no-repeat -64px -8px; +} + +#synopsis p.caption.expander { + background: url(synopsis.png) no-repeat 0px -8px; +} + +#synopsis ul { + height: 100%; + overflow: auto; + padding: 0.5em; + margin: 0; +} + +#synopsis ul ul { + overflow: hidden; +} + +#synopsis ul, +#synopsis ul li.src { + background-color: #faf9dc; + white-space: nowrap; + list-style: none; + margin-left: 0; +} + +/* @end */ + +/* @group Main Content */ + +#interface div.top { margin: 2em 0; } +#interface h1 + div.top, +#interface h2 + div.top, +#interface h3 + div.top, +#interface h4 + div.top, +#interface h5 + div.top { + margin-top: 1em; +} +#interface .src .selflink, +#interface .src .link { + float: right; + color: #919191; + background: #f0f0f0; + padding: 0 0.5em 0.2em; + margin: 0 -0.5em 0 0; +} +#interface .src .selflink { + border-left: 1px solid #919191; + margin: 0 -0.5em 0 0.5em; +} + +#interface span.fixity { + color: #919191; + border-left: 1px solid #919191; + padding: 0.2em 0.5em 0.2em 0.5em; + margin: 0 -1em 0 1em; +} + +#interface span.rightedge { + border-left: 1px solid #919191; + padding: 0.2em 0 0.2em 0; + margin: 0 0 0 1em; +} + +#interface table { border-spacing: 2px; } +#interface td { + vertical-align: top; + padding-left: 0.5em; +} +#interface td.src { + white-space: nowrap; +} +#interface td.doc p { + margin: 0; +} +#interface td.doc p + p { + margin-top: 0.8em; +} + +.clearfix:after { + clear: both; + content: " "; + display: block; + height: 0; + visibility: hidden; +} + +.subs ul { + list-style: none; + display: table; + margin: 0; +} + +.subs ul li { + display: table-row; +} + +.subs ul li dfn { + display: table-cell; + font-style: normal; + font-weight: bold; + margin: 1px 0; + white-space: nowrap; +} + +.subs ul li > .doc { + display: table-cell; + padding-left: 0.5em; + margin-bottom: 0.5em; +} + +.subs ul li > .doc p { + margin: 0; +} + +/* Render short-style data instances */ +.inst ul { + height: 100%; + padding: 0.5em; + margin: 0; +} + +.inst, .inst li { + list-style: none; + margin-left: 1em; +} + +/* Workaround for bug in Firefox (issue #384) */ +.inst-left { + float: left; +} + +.top p.src { + border-top: 1px solid #ccc; +} + +.subs, .doc { + /* use this selector for one level of indent */ + padding-left: 2em; +} + +.warning { + color: red; +} + +.arguments { + margin-top: -0.4em; +} +.arguments .caption { + display: none; +} + +.fields { padding-left: 1em; } + +.fields .caption { display: none; } + +.fields p { margin: 0 0; } + +/* this seems bulky to me +.methods, .constructors { + background: #f8f8f8; + border: 1px solid #eee; +} +*/ + +/* @end */ + +/* @group Auxillary Pages */ + + +.extension-list { + list-style-type: none; + margin-left: 0; +} + +#mini { + margin: 0 auto; + padding: 0 1em 1em; +} + +#mini > * { + font-size: 93%; /* 12pt */ +} + +#mini #module-list .caption, +#mini #module-header .caption { + font-size: 125%; /* 15pt */ +} + +#mini #interface h1, +#mini #interface h2, +#mini #interface h3, +#mini #interface h4 { + font-size: 109%; /* 13pt */ + margin: 1em 0 0; +} + +#mini #interface .top, +#mini #interface .src { + margin: 0; +} + +#mini #module-list ul { + list-style: none; + margin: 0; +} + +#alphabet ul { + list-style: none; + padding: 0; + margin: 0.5em 0 0; + text-align: center; +} + +#alphabet li { + display: inline; + margin: 0 0.25em; +} + +#alphabet a { + font-weight: bold; +} + +#index .caption, +#module-list .caption { font-size: 131%; /* 17pt */ } + +#index table { + margin-left: 2em; +} + +#index .src { + font-weight: bold; +} +#index .alt { + font-size: 77%; /* 10pt */ + font-style: italic; + padding-left: 2em; +} + +#index td + td { + padding-left: 1em; +} + +#module-list ul { + list-style: none; + margin: 0 0 0 2em; +} + +#module-list li { + clear: right; +} + +#module-list span.collapser, +#module-list span.expander { + background-position: 0 0.3em; +} + +#module-list .package { + float: right; +} + +/* @end */ diff --git a/static/typed-process/plus.gif b/static/typed-process/plus.gif new file mode 100644 index 0000000..2d15c14 Binary files /dev/null and b/static/typed-process/plus.gif differ diff --git a/static/typed-process/src/System.Process.Typed.html b/static/typed-process/src/System.Process.Typed.html new file mode 100644 index 0000000..c658de2 --- /dev/null +++ b/static/typed-process/src/System.Process.Typed.html @@ -0,0 +1,728 @@ +
    {-# LANGUAGE CPP #-}
    +{-# LANGUAGE TypeFamilies #-}
    +{-# LANGUAGE DeriveDataTypeable #-}
    +{-# LANGUAGE RecordWildCards #-}
    +{-# LANGUAGE DataKinds #-}
    +{-# LANGUAGE KindSignatures #-}
    +{-# LANGUAGE DeriveFunctor #-}
    +-- | Please see the README.md file for examples of using this API.
    +module System.Process.Typed
    +    ( -- * Types
    +      ProcessConfig
    +    , StreamSpec
    +    , StreamType (..)
    +    , Process
    +
    +      -- * ProcessConfig
    +      -- ** Smart constructors
    +    , proc
    +    , shell
    +
    +      -- ** Setters
    +    , setStdin
    +    , setStdout
    +    , setStderr
    +    , setWorkingDir
    +    , setEnv
    +    , setCloseFds
    +    , setCreateGroup
    +    , setDelegateCtlc
    +#if MIN_VERSION_process(1, 3, 0)
    +    , setDetachConsole
    +    , setCreateNewConsole
    +    , setNewSession
    +#endif
    +#if MIN_VERSION_process(1, 4, 0) && !WINDOWS
    +    , setChildGroup
    +    , setChildUser
    +#endif
    +    , setCheckExitCode
    +
    +      -- * Stream specs
    +    , mkStreamSpec
    +    , inherit
    +    , closed
    +    , byteStringInput
    +    , byteStringOutput
    +    , createPipe
    +    , useHandleOpen
    +    , useHandleClose
    +    , sink
    +    , source
    +
    +      -- * Launch a process
    +    , startProcess
    +    , stopProcess
    +    , withProcess
    +    , readProcess
    +    , runProcess
    +    , runProcess_
    +
    +      -- * Interact with a process
    +
    +      -- ** Process exit code
    +    , waitExitCode
    +    , waitExitCodeSTM
    +    , checkExitCode
    +    , checkExitCodeSTM
    +
    +      -- ** Process streams
    +    , getStdin
    +    , getStdout
    +    , getStderr
    +
    +      -- * Exceptions
    +    , ExitCodeException (..)
    +    , ByteStringOutputException (..)
    +    ) where
    +
    +import qualified Data.ByteString as S
    +import Data.ByteString.Lazy.Internal (defaultChunkSize)
    +import Control.Exception (throw, throwIO)
    +import Control.Monad (void)
    +import Control.Monad.IO.Class
    +import qualified System.Process as P
    +import Control.Monad.Catch as C
    +import Data.Typeable (Typeable)
    +import System.IO (Handle, hClose)
    +import Control.Concurrent.Async (async)
    +import Control.Concurrent.STM (newEmptyTMVarIO, atomically, putTMVar, TMVar, readTMVar, tryReadTMVar, STM, tryPutTMVar, throwSTM)
    +import System.Exit (ExitCode (ExitSuccess))
    +import qualified Data.ByteString.Lazy as L
    +import Data.String (IsString (fromString))
    +import Data.Conduit (ConduitM)
    +import qualified Data.Conduit as C
    +import qualified Data.Conduit.Binary as CB
    +
    +#if MIN_VERSION_process(1, 4, 0) && !WINDOWS
    +import System.Posix.Types (GroupID, UserID)
    +#endif
    +
    +-- | An abstract configuration for a process, which can then be
    +-- launched into an actual running 'Process'. Takes three type
    +-- parameters, providing the types of standard input, standard output,
    +-- and standard error, respectively.
    +--
    +-- There are three ways to construct a value of this type:
    +--
    +-- * With the 'proc' smart constructor, which takes a command name and
    +-- a list of arguments.
    +--
    +-- * With the 'shell' smart constructor, which takes a shell string
    +--
    +-- * With the 'IsString' instance via OverloadedStrings. If you
    +-- provide it a string with no spaces (e.g., @"date"@), it will
    +-- treat it as a raw command with no arguments (e.g., @proc "date"
    +-- []@). If it has spaces, it will use @shell@.
    +--
    +-- In all cases, the default for all three streams is to inherit the
    +-- streams from the parent process. For other settings, see the
    +-- setters below for default values.
    +--
    +-- @since 0.1.0.0
    +data ProcessConfig stdin stdout stderr = ProcessConfig
    +    { pcCmdSpec :: !P.CmdSpec
    +    , pcStdin :: !(StreamSpec 'STInput stdin)
    +    , pcStdout :: !(StreamSpec 'STOutput stdout)
    +    , pcStderr :: !(StreamSpec 'STOutput stderr)
    +    , pcWorkingDir :: !(Maybe FilePath)
    +    , pcEnv :: !(Maybe [(String, String)])
    +    , pcCloseFds :: !Bool
    +    , pcCreateGroup :: !Bool
    +    , pcDelegateCtlc :: !Bool
    +
    +#if MIN_VERSION_process(1, 3, 0)
    +    , pcDetachConsole :: !Bool
    +    , pcCreateNewConsole :: !Bool
    +    , pcNewSession :: !Bool
    +#endif
    +
    +#if MIN_VERSION_process(1, 4, 0) && !WINDOWS
    +    , pcChildGroup :: !(Maybe GroupID)
    +    , pcChildUser :: !(Maybe UserID)
    +#endif
    +
    +    , pcCheckExitCode :: !Bool
    +    }
    +instance (stdin ~ (), stdout ~ (), stderr ~ ())
    +  => IsString (ProcessConfig stdin stdout stderr) where
    +    fromString s
    +        | any (== ' ') s = shell s
    +        | otherwise = proc s []
    +
    +-- | Whether a stream is an input stream or output stream. Note that
    +-- this is from the perspective of the /child process/, so that a
    +-- child's standard input stream is an @STInput@, even though the
    +-- parent process will be writing to it.
    +--
    +-- @since 0.1.0.0
    +data StreamType = STInput | STOutput
    +
    +-- | A specification for how to create one of the three standard child
    +-- streams. See examples below.
    +--
    +-- @since 0.1.0.0
    +data StreamSpec (streamType :: StreamType) a = StreamSpec
    +    { ssStream :: !P.StdStream
    +    , ssCreate :: !(Maybe Handle -> Cleanup a)
    +    }
    +    deriving Functor
    +
    +-- | This instance uses 'byteStringInput' to convert a raw string into
    +-- a stream of input for a child process.
    +--
    +-- @since 0.1.0.0
    +instance (streamType ~ 'STInput, res ~ ())
    +  => IsString (StreamSpec streamType res) where
    +    fromString = byteStringInput . fromString
    +
    +-- | Internal type, to make for easier composition of cleanup actions.
    +--
    +-- @since 0.1.0.0
    +newtype Cleanup a = Cleanup { runCleanup :: IO (a, IO ()) }
    +    deriving Functor
    +instance Applicative Cleanup where
    +    pure x = Cleanup (return (x, return ()))
    +    Cleanup f <*> Cleanup x = Cleanup $ do
    +        (f', c1) <- f
    +        (`onException` c1) $ do
    +            (x', c2) <- x
    +            return (f' x', c1 `finally` c2)
    +
    +-- | A running process. The three type parameters provide the type of
    +-- the standard input, standard output, and standard error streams.
    +--
    +-- @since 0.1.0.0
    +data Process stdin stdout stderr = Process
    +    { pCleanup :: !(IO ())
    +    , pStdin :: !stdin
    +    , pStdout :: !stdout
    +    , pStderr :: !stderr
    +    , pHandle :: !P.ProcessHandle
    +    , pExitCode :: !(TMVar ExitCode)
    +    }
    +
    +-- | Internal helper
    +defaultProcessConfig :: ProcessConfig () () ()
    +defaultProcessConfig = ProcessConfig
    +    { pcCmdSpec = P.ShellCommand ""
    +    , pcStdin = inherit
    +    , pcStdout = inherit
    +    , pcStderr = inherit
    +    , pcWorkingDir = Nothing
    +    , pcEnv = Nothing
    +    , pcCloseFds = False
    +    , pcCreateGroup = False
    +    , pcDelegateCtlc = False
    +
    +#if MIN_VERSION_process(1, 3, 0)
    +    , pcDetachConsole = False
    +    , pcCreateNewConsole = False
    +    , pcNewSession = False
    +#endif
    +
    +#if MIN_VERSION_process(1, 4, 0) && !WINDOWS
    +    , pcChildGroup = Nothing
    +    , pcChildUser = Nothing
    +#endif
    +
    +    , pcCheckExitCode = False
    +    }
    +
    +-- | Create a 'ProcessConfig' from the given command and arguments.
    +--
    +-- @since 0.1.0.0
    +proc :: FilePath -> [String] -> ProcessConfig () () ()
    +proc cmd args = setProc cmd args defaultProcessConfig
    +
    +-- | Internal helper
    +setProc :: FilePath -> [String]
    +        -> ProcessConfig stdin stdout stderr
    +        -> ProcessConfig stdin stdout stderr
    +setProc cmd args p = p { pcCmdSpec = P.RawCommand cmd args }
    +
    +-- | Create a 'ProcessConfig' from the given shell command.
    +--
    +-- @since 0.1.0.0
    +shell :: String -> ProcessConfig () () ()
    +shell cmd = setShell cmd defaultProcessConfig
    +
    +-- | Internal helper
    +setShell :: String
    +         -> ProcessConfig stdin stdout stderr
    +         -> ProcessConfig stdin stdout stderr
    +setShell cmd p = p { pcCmdSpec = P.ShellCommand cmd }
    +
    +-- | Set the child's standard input stream to the given 'StreamSpec'.
    +--
    +-- Default: 'inherit'
    +--
    +-- @since 0.1.0.0
    +setStdin :: StreamSpec 'STInput stdin
    +         -> ProcessConfig stdin0 stdout stderr
    +         -> ProcessConfig stdin stdout stderr
    +setStdin spec pc = pc { pcStdin = spec }
    +
    +-- | Set the child's standard output stream to the given 'StreamSpec'.
    +--
    +-- Default: 'inherit'
    +--
    +-- @since 0.1.0.0
    +setStdout :: StreamSpec 'STOutput stdout
    +          -> ProcessConfig stdin stdout0 stderr
    +          -> ProcessConfig stdin stdout stderr
    +setStdout spec pc = pc { pcStdout = spec }
    +
    +-- | Set the child's standard error stream to the given 'StreamSpec'.
    +--
    +-- Default: 'inherit'
    +--
    +-- @since 0.1.0.0
    +setStderr :: StreamSpec 'STOutput stderr
    +          -> ProcessConfig stdin stdout stderr0
    +          -> ProcessConfig stdin stdout stderr
    +setStderr spec pc = pc { pcStderr = spec }
    +
    +-- | Set the working directory of the child process.
    +--
    +-- Default: current process's working directory.
    +--
    +-- @since 0.1.0.0
    +setWorkingDir :: FilePath
    +              -> ProcessConfig stdin stdout stderr
    +              -> ProcessConfig stdin stdout stderr
    +setWorkingDir dir pc = pc { pcWorkingDir = Just dir }
    +
    +-- | Set the environment variables of the child process.
    +--
    +-- Default: current process's environment.
    +--
    +-- @since 0.1.0.0
    +setEnv :: [(String, String)]
    +       -> ProcessConfig stdin stdout stderr
    +       -> ProcessConfig stdin stdout stderr
    +setEnv env pc = pc { pcEnv = Just env }
    +
    +-- | Should we close all file descriptors besides stdin, stdout, and
    +-- stderr? See 'P.close_fds' for more information.
    +--
    +-- Default: False
    +--
    +-- @since 0.1.0.0
    +setCloseFds
    +    :: Bool
    +    -> ProcessConfig stdin stdout stderr
    +    -> ProcessConfig stdin stdout stderr
    +setCloseFds x pc = pc { pcCloseFds = x }
    +
    +-- | Should we create a new process group?
    +--
    +-- Default: False
    +--
    +-- @since 0.1.0.0
    +setCreateGroup
    +    :: Bool
    +    -> ProcessConfig stdin stdout stderr
    +    -> ProcessConfig stdin stdout stderr
    +setCreateGroup x pc = pc { pcCreateGroup = x }
    +
    +-- | Delegate handling of Ctrl-C to the child. For more information,
    +-- see 'P.delegate_ctlc'.
    +--
    +-- Default: False
    +--
    +-- @since 0.1.0.0
    +setDelegateCtlc
    +    :: Bool
    +    -> ProcessConfig stdin stdout stderr
    +    -> ProcessConfig stdin stdout stderr
    +setDelegateCtlc x pc = pc { pcDelegateCtlc = x }
    +
    +#if MIN_VERSION_process(1, 3, 0)
    +
    +-- | Detach console on Windows, see 'P.detach_console'.
    +--
    +-- Default: False
    +--
    +-- @since 0.1.0.0
    +setDetachConsole
    +    :: Bool
    +    -> ProcessConfig stdin stdout stderr
    +    -> ProcessConfig stdin stdout stderr
    +setDetachConsole x pc = pc { pcDetachConsole = x }
    +
    +-- | Create new console on Windows, see 'P.create_new_console'.
    +--
    +-- Default: False
    +--
    +-- @since 0.1.0.0
    +setCreateNewConsole
    +    :: Bool
    +    -> ProcessConfig stdin stdout stderr
    +    -> ProcessConfig stdin stdout stderr
    +setCreateNewConsole x pc = pc { pcCreateNewConsole = x }
    +
    +-- | Set a new session with the POSIX @setsid@ syscall, does nothing
    +-- on non-POSIX. See 'P.new_session'.
    +--
    +-- Default: False
    +--
    +-- @since 0.1.0.0
    +setNewSession
    +    :: Bool
    +    -> ProcessConfig stdin stdout stderr
    +    -> ProcessConfig stdin stdout stderr
    +setNewSession x pc = pc { pcNewSession = x }
    +#endif
    +
    +#if MIN_VERSION_process(1, 4, 0) && !WINDOWS
    +-- | Set the child process's group ID with the POSIX @setgid@ syscall,
    +-- does nothing on non-POSIX. See 'P.child_group'.
    +--
    +-- Default: False
    +--
    +-- @since 0.1.0.0
    +setChildGroup
    +    :: GroupID
    +    -> ProcessConfig stdin stdout stderr
    +    -> ProcessConfig stdin stdout stderr
    +setChildGroup x pc = pc { pcChildGroup = Just x }
    +
    +-- | Set the child process's user ID with the POSIX @setuid@ syscall,
    +-- does nothing on non-POSIX. See 'P.child_user'.
    +--
    +-- Default: False
    +--
    +-- @since 0.1.0.0
    +setChildUser
    +    :: UserID
    +    -> ProcessConfig stdin stdout stderr
    +    -> ProcessConfig stdin stdout stderr
    +setChildUser x pc = pc { pcChildUser = Just x }
    +#endif
    +
    +-- | Should we throw an exception when the process exits with a
    +-- non-success code?
    +--
    +-- If set to 'True', then when 'stopProcess' is called - either
    +-- directly or via 'withProcess' or other wrappers - the processes
    +-- exit code will be checked. Any exit code besides 'ExitSuccess' will
    +-- result in an 'ExitCodeException' being thrown.
    +--
    +-- Default: 'False'
    +--
    +-- @since 0.1.0.0
    +setCheckExitCode :: Bool
    +                 -> ProcessConfig stdin stdout stderr
    +                 -> ProcessConfig stdin stdout stderr
    +setCheckExitCode x p = p { pcCheckExitCode = x }
    +
    +-- TODO: Instead of having this setting, we could consider just having
    +-- alternatives to readProcess, runProcess, etc, that check the exit
    +-- code. This could actually be a really nice convention: readProcess
    +-- does not check, readProcess_ or readProcessCheck does.
    +
    +-- | Create a new 'StreamSpec' from the given 'P.StdStream' and a
    +-- helper function. This function:
    +--
    +-- * Takes as input the raw @Maybe Handle@ returned by the
    +-- 'P.createProcess' function. This will be determined by the
    +-- 'P.StdStream' argument.
    +--
    +-- * Returns the actual stream value @a@, as well as a cleanup
    +-- * function to be run when calling 'stopProcess'.
    +--
    +-- @since 0.1.0.0
    +mkStreamSpec :: P.StdStream
    +             -> (Maybe Handle -> IO (a, IO ()))
    +             -> StreamSpec streamType a
    +mkStreamSpec ss f = StreamSpec ss (Cleanup . f)
    +
    +-- | A stream spec which simply inherits the stream of the parent
    +-- process.
    +--
    +-- @since 0.1.0.0
    +inherit :: StreamSpec anyStreamType ()
    +inherit = mkStreamSpec P.Inherit (\Nothing -> pure ((), return ()))
    +
    +-- | A stream spec which will close the stream for the child process.
    +--
    +-- @since 0.1.0.0
    +closed :: StreamSpec anyStreamType ()
    +#if MIN_VERSION_process(1, 4, 0)
    +closed = mkStreamSpec P.NoStream (\Nothing -> pure ((), return ()))
    +#else
    +closed = mkStreamSpec P.CreatePipe (\(Just h) -> (((), return ()) <$ hClose h))
    +#endif
    +
    +-- | An input stream spec which sets the input to the given
    +-- 'L.ByteString'. A separate thread will be forked to write the
    +-- contents to the child process.
    +--
    +-- @since 0.1.0.0
    +byteStringInput :: L.ByteString -> StreamSpec 'STInput ()
    +byteStringInput lbs = StreamSpec P.CreatePipe $ \(Just h) -> Cleanup $ do
    +    void $ async $ do
    +        L.hPut h lbs
    +        hClose h
    +    return ((), hClose h)
    +
    +-- | Capture the output of a process in a 'L.ByteString'.
    +--
    +-- This function will fork a separate thread to consume all input from
    +-- the process, and will only make the results available when the
    +-- underlying 'Handle' is closed. As this is provided as an 'STM'
    +-- action, you can either check if the result is available, or block
    +-- until it's ready.
    +--
    +-- In the event of any exception occurring when reading from the
    +-- 'Handle', the result of this function will be a 'Left' value
    +-- containing a 'ByteStringOutputException'.
    +--
    +-- @since 0.1.0.0
    +byteStringOutput :: StreamSpec 'STOutput (STM (Either ByteStringOutputException L.ByteString))
    +byteStringOutput = StreamSpec P.CreatePipe $ \(Just h) -> Cleanup $ do
    +    mvar <- newEmptyTMVarIO
    +
    +    void $ async $ do
    +        let loop front = do
    +                bs <- S.hGetSome h defaultChunkSize
    +                if S.null bs
    +                    then atomically $ putTMVar mvar $ Right $ L.fromChunks $ front []
    +                    else loop $ front . (bs:)
    +        loop id `catch` \e -> do
    +            atomically $ void $ tryPutTMVar mvar $ Left $ ByteStringOutputException e
    +            throwIO e
    +
    +    return (readTMVar mvar, hClose h)
    +
    +-- | Create a new pipe between this process and the child, and return
    +-- a 'Handle' to communicate with the child.
    +--
    +-- @since 0.1.0.0
    +createPipe :: StreamSpec anyStreamType Handle
    +createPipe = StreamSpec P.CreatePipe $ \(Just h) -> Cleanup $ return (h, hClose h)
    +
    +-- | Use the provided 'Handle' for the child process, and when the
    +-- process exits, do /not/ close it. This is useful if, for example,
    +-- you want to have multiple processes write to the same log file
    +-- sequentially.
    +--
    +-- @since 0.1.0.0
    +useHandleOpen :: Handle -> StreamSpec anyStreamType ()
    +useHandleOpen h = StreamSpec (P.UseHandle h) $ \Nothing -> Cleanup $ return ((), return ())
    +
    +-- | Use the provided 'Handle' for the child process, and when the
    +-- process exits, close it. If you have no reason to keep the 'Handle'
    +-- open, you should use this over 'useHandleOpen'.
    +--
    +-- @since 0.1.0.0
    +useHandleClose :: Handle -> StreamSpec anyStreamType ()
    +useHandleClose h = StreamSpec (P.UseHandle h) $ \Nothing -> Cleanup $ return ((), hClose h)
    +
    +-- | Provide input to a process by writing to a conduit.
    +--
    +-- @since 0.1.0.0
    +sink :: MonadIO m => StreamSpec 'STInput (ConduitM S.ByteString o m ())
    +sink =
    +    (\h -> C.addCleanup (\_ -> liftIO $ hClose h) (CB.sinkHandle h))
    +    <$> createPipe
    +
    +-- | Read output from a process by read from a conduit.
    +--
    +-- @since 0.1.0.0
    +source :: MonadIO m => StreamSpec 'STOutput (ConduitM i S.ByteString m ())
    +source =
    +    (\h -> C.addCleanup (\_ -> liftIO $ hClose h) (CB.sourceHandle h))
    +    <$> createPipe
    +
    +-- | Launch a process based on the given 'ProcessConfig'. You should
    +-- ensure that you close 'stopProcess' on the result. It's usually
    +-- better to use one of the functions in this module which ensures
    +-- 'stopProcess' is called, such as 'withProcess'.
    +--
    +-- @since 0.1.0.0
    +startProcess :: MonadIO m
    +             => ProcessConfig stdin stdout stderr
    +             -> m (Process stdin stdout stderr)
    +startProcess ProcessConfig {..} = liftIO $ do
    +    let cp0 =
    +            case pcCmdSpec of
    +                P.ShellCommand cmd -> P.shell cmd
    +                P.RawCommand cmd args -> P.proc cmd args
    +        cp = cp0
    +            { P.std_in = ssStream pcStdin
    +            , P.std_out = ssStream pcStdout
    +            , P.std_err = ssStream pcStderr
    +            , P.cwd = pcWorkingDir
    +            , P.env = pcEnv
    +            , P.close_fds = pcCloseFds
    +            , P.create_group = pcCreateGroup
    +            , P.delegate_ctlc = pcDelegateCtlc
    +
    +#if MIN_VERSION_process(1, 3, 0)
    +            , P.detach_console = pcDetachConsole
    +            , P.create_new_console = pcCreateNewConsole
    +            , P.new_session = pcNewSession
    +#endif
    +
    +#if MIN_VERSION_process(1, 4, 0) && !WINDOWS
    +            , P.child_group = pcChildGroup
    +            , P.child_user = pcChildUser
    +#endif
    +
    +            }
    +
    +    (minH, moutH, merrH, pHandle) <- P.createProcess_ "startProcess" cp
    +
    +    ((pStdin, pStdout, pStderr), pCleanup1) <- runCleanup $ (,,)
    +        <$> ssCreate pcStdin minH
    +        <*> ssCreate pcStdout moutH
    +        <*> ssCreate pcStderr merrH
    +
    +    pExitCode <- newEmptyTMVarIO
    +    void $ async $ do
    +        ec <- P.waitForProcess pHandle
    +        atomically $ putTMVar pExitCode ec
    +
    +    let pCleanup2 = pCleanup1 `finally` do
    +            mec <- atomically $ tryReadTMVar pExitCode
    +            case mec of
    +                Nothing -> do
    +                    P.terminateProcess pHandle
    +                    -- TODO: should we put in a timeout and then send
    +                    -- a SIGKILL on Unix?
    +                    void $ atomically $ readTMVar pExitCode
    +                Just _ -> return ()
    +        pCleanup
    +            | pcCheckExitCode = do
    +                eres <- try pCleanup2
    +                ec <- atomically $ readTMVar pExitCode
    +                case (ec, eres) of
    +                    (ExitSuccess, Right ()) -> return ()
    +                    (ExitSuccess, Left e) -> throwIO e
    +                    _ -> throwIO $ ExitCodeException ec $ either Just (const Nothing) eres
    +            | otherwise = pCleanup2
    +
    +    return Process {..}
    +
    +-- | Close a process and release any resources acquired. This will
    +-- ensure 'P.terminateProcess' is called, wait for the process to
    +-- actually exit, and then close out resources allocated for the
    +-- streams. In the event of any cleanup exceptions being thrown, or if
    +-- a non-success exit code was received and 'setCheckExitCode' was
    +-- used, this will throw an exception.
    +--
    +-- @since 0.1.0.0
    +stopProcess :: MonadIO m
    +            => Process stdin stdout stderr
    +            -> m ()
    +stopProcess = liftIO . pCleanup
    +
    +-- | Use the bracket pattern to call 'startProcess' and ensure
    +-- 'stopProcess' is called.
    +--
    +-- @since 0.1.0.0
    +withProcess :: (MonadIO m, C.MonadMask m)
    +            => ProcessConfig stdin stdout stderr
    +            -> (Process stdin stdout stderr -> m a)
    +            -> m a
    +withProcess config = C.bracket (startProcess config) stopProcess
    +
    +-- | Run a process, capture its standard output and error as a
    +-- 'L.ByteString', wait for it to complete, and then return its exit
    +-- code, output, and error.
    +--
    +-- Note that any previously used 'setStdout' or 'setStderr' will be
    +-- overridden.
    +--
    +-- @since 0.1.0.0
    +readProcess :: MonadIO m
    +            => ProcessConfig stdin stdoutIgnored stderrIgnored
    +            -> m (ExitCode, L.ByteString, L.ByteString)
    +readProcess pc =
    +    liftIO $ withProcess pc' $ \p -> atomically $ (,,)
    +        <$> waitExitCodeSTM p
    +        <*> (getStdout p >>= either throwSTM return)
    +        <*> (getStderr p >>= either throwSTM return)
    +  where
    +    pc' = setStdout byteStringOutput
    +        $ setStderr byteStringOutput pc
    +
    +-- | Run the given process, wait for it to exit, and returns its
    +-- 'ExitCode'.
    +--
    +-- @since 0.1.0.0
    +runProcess :: MonadIO m
    +           => ProcessConfig stdin stdout stderr
    +           -> m ExitCode
    +runProcess pc = liftIO $ withProcess pc waitExitCode
    +
    +-- | Same as 'runProcess', but ignores the 'ExitCode'.
    +--
    +-- @since 0.1.0.0
    +runProcess_ :: MonadIO m
    +            => ProcessConfig stdin stdout stderr
    +            -> m ()
    +runProcess_ = void . runProcess
    +
    +-- | Wait for the process to exit and then return its 'ExitCode'.
    +--
    +-- @since 0.1.0.0
    +waitExitCode :: MonadIO m => Process stdin stdout stderr -> m ExitCode
    +waitExitCode = liftIO . atomically . waitExitCodeSTM
    +
    +-- | Same as 'waitExitCode', but in 'STM'.
    +--
    +-- @since 0.1.0.0
    +waitExitCodeSTM :: Process stdin stdout stderr -> STM ExitCode
    +waitExitCodeSTM = readTMVar . pExitCode
    +
    +-- | Check if a process has exited and, if so, return its 'ExitCode'.
    +--
    +-- @since 0.1.0.0
    +checkExitCode :: MonadIO m => Process stdin stdout stderr -> m (Maybe ExitCode)
    +checkExitCode = liftIO . atomically . checkExitCodeSTM
    +
    +-- | Same as 'checkExitCode', but in 'STM'.
    +--
    +-- @since 0.1.0.0
    +checkExitCodeSTM :: Process stdin stdout stderr -> STM (Maybe ExitCode)
    +checkExitCodeSTM = tryReadTMVar . pExitCode
    +
    +-- | Get the child's standard input stream value.
    +--
    +-- @since 0.1.0.0
    +getStdin :: Process stdin stdout stderr -> stdin
    +getStdin = pStdin
    +
    +-- | Get the child's standard output stream value.
    +--
    +-- @since 0.1.0.0
    +getStdout :: Process stdin stdout stderr -> stdout
    +getStdout = pStdout
    +
    +-- | Get the child's standard error stream value.
    +--
    +-- @since 0.1.0.0
    +getStderr :: Process stdin stdout stderr -> stderr
    +getStderr = pStderr
    +
    +-- | Exit code generated by 'stopProcess' when 'setCheckExitCode' is
    +-- 'True' and a process exits with a non-success code. Contains the
    +-- non-success code, and if any other exceptions occur during cleanup,
    +-- that exception.
    +--
    +-- @since 0.1.0.0
    +data ExitCodeException = ExitCodeException ExitCode (Maybe SomeException)
    +    deriving (Show, Typeable)
    +instance Exception ExitCodeException
    +
    +-- | Wrapper for when an exception is thrown when reading from a child
    +-- process, used by 'byteStringOutput'.
    +--
    +-- @since 0.1.0.0
    +newtype ByteStringOutputException = ByteStringOutputException SomeException
    +    deriving (Show, Typeable)
    +instance Exception ByteStringOutputException
    +
    \ No newline at end of file diff --git a/static/typed-process/src/highlight.js b/static/typed-process/src/highlight.js new file mode 100644 index 0000000..1e903bd --- /dev/null +++ b/static/typed-process/src/highlight.js @@ -0,0 +1,27 @@ + +var highlight = function (on) { + return function () { + var links = document.getElementsByTagName('a'); + for (var i = 0; i < links.length; i++) { + var that = links[i]; + + if (this.href != that.href) { + continue; + } + + if (on) { + that.classList.add("hover-highlight"); + } else { + that.classList.remove("hover-highlight"); + } + } + } +}; + +window.onload = function () { + var links = document.getElementsByTagName('a'); + for (var i = 0; i < links.length; i++) { + links[i].onmouseover = highlight(true); + links[i].onmouseout = highlight(false); + } +}; diff --git a/static/typed-process/src/style.css b/static/typed-process/src/style.css new file mode 100644 index 0000000..e83dc5e --- /dev/null +++ b/static/typed-process/src/style.css @@ -0,0 +1,55 @@ +body { + background-color: #fdf6e3; +} + +.hs-identifier { + color: #073642; +} + +.hs-identifier.hs-var { +} + +.hs-identifier.hs-type { + color: #5f5faf; +} + +.hs-keyword { + color: #af005f; +} + +.hs-string, .hs-char { + color: #cb4b16; +} + +.hs-number { + color: #268bd2; +} + +.hs-operator { + color: #d33682; +} + +.hs-glyph, .hs-special { + color: #dc322f; +} + +.hs-comment { + color: #8a8a8a; +} + +.hs-pragma { + color: #2aa198; +} + +.hs-cpp { + color: #859900; +} + +a:link, a:visited { + text-decoration: none; + border-bottom: 1px solid #eee8d5; +} + +a:hover, a.hover-highlight { + background-color: #eee8d5; +} diff --git a/static/typed-process/synopsis.png b/static/typed-process/synopsis.png new file mode 100644 index 0000000..85fb86e Binary files /dev/null and b/static/typed-process/synopsis.png differ diff --git a/static/typed-process/typed-process.haddock b/static/typed-process/typed-process.haddock new file mode 100644 index 0000000..d53a2a4 Binary files /dev/null and b/static/typed-process/typed-process.haddock differ diff --git a/static/typed-process/typed-process.txt b/static/typed-process/typed-process.txt new file mode 100644 index 0000000..d1a770a --- /dev/null +++ b/static/typed-process/typed-process.txt @@ -0,0 +1,272 @@ +-- Hoogle documentation, generated by Haddock +-- See Hoogle, http://www.haskell.org/hoogle/ + + +-- | Alternative API for processes, featuring more type safety +-- +-- Please see README.md +@package typed-process +@version 0.1.0.0 + + +-- | Please see the README.md file for examples of using this API. +module System.Process.Typed + +-- | An abstract configuration for a process, which can then be launched +-- into an actual running Process. Takes three type parameters, +-- providing the types of standard input, standard output, and standard +-- error, respectively. +-- +-- There are three ways to construct a value of this type: +-- +-- +-- +-- In all cases, the default for all three streams is to inherit the +-- streams from the parent process. For other settings, see the setters +-- below for default values. +data ProcessConfig stdin stdout stderr + +-- | A specification for how to create one of the three standard child +-- streams. See examples below. +data StreamSpec (streamType :: StreamType) a + +-- | Whether a stream is an input stream or output stream. Note that this +-- is from the perspective of the child process, so that a child's +-- standard input stream is an STInput, even though the parent +-- process will be writing to it. +data StreamType +STInput :: StreamType +STOutput :: StreamType + +-- | A running process. The three type parameters provide the type of the +-- standard input, standard output, and standard error streams. +data Process stdin stdout stderr + +-- | Create a ProcessConfig from the given command and arguments. +proc :: FilePath -> [String] -> ProcessConfig () () () + +-- | Create a ProcessConfig from the given shell command. +shell :: String -> ProcessConfig () () () + +-- | Set the child's standard input stream to the given StreamSpec. +-- +-- Default: inherit +setStdin :: StreamSpec STInput stdin -> ProcessConfig stdin0 stdout stderr -> ProcessConfig stdin stdout stderr + +-- | Set the child's standard output stream to the given StreamSpec. +-- +-- Default: inherit +setStdout :: StreamSpec STOutput stdout -> ProcessConfig stdin stdout0 stderr -> ProcessConfig stdin stdout stderr + +-- | Set the child's standard error stream to the given StreamSpec. +-- +-- Default: inherit +setStderr :: StreamSpec STOutput stderr -> ProcessConfig stdin stdout stderr0 -> ProcessConfig stdin stdout stderr + +-- | Set the working directory of the child process. +-- +-- Default: current process's working directory. +setWorkingDir :: FilePath -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr + +-- | Set the environment variables of the child process. +-- +-- Default: current process's environment. +setEnv :: [(String, String)] -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr + +-- | Should we close all file descriptors besides stdin, stdout, and +-- stderr? See close_fds for more information. +-- +-- Default: False +setCloseFds :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr + +-- | Should we create a new process group? +-- +-- Default: False +setCreateGroup :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr + +-- | Delegate handling of Ctrl-C to the child. For more information, see +-- delegate_ctlc. +-- +-- Default: False +setDelegateCtlc :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr + +-- | Detach console on Windows, see detach_console. +-- +-- Default: False +setDetachConsole :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr + +-- | Create new console on Windows, see create_new_console. +-- +-- Default: False +setCreateNewConsole :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr + +-- | Set a new session with the POSIX setsid syscall, does nothing +-- on non-POSIX. See new_session. +-- +-- Default: False +setNewSession :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr + +-- | Set the child process's group ID with the POSIX setgid +-- syscall, does nothing on non-POSIX. See child_group. +-- +-- Default: False +setChildGroup :: GroupID -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr + +-- | Set the child process's user ID with the POSIX setuid +-- syscall, does nothing on non-POSIX. See child_user. +-- +-- Default: False +setChildUser :: UserID -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr + +-- | Should we throw an exception when the process exits with a non-success +-- code? +-- +-- If set to True, then when stopProcess is called - either +-- directly or via withProcess or other wrappers - the processes +-- exit code will be checked. Any exit code besides ExitSuccess +-- will result in an ExitCodeException being thrown. +-- +-- Default: False +setCheckExitCode :: Bool -> ProcessConfig stdin stdout stderr -> ProcessConfig stdin stdout stderr + +-- | Create a new StreamSpec from the given StdStream and a +-- helper function. This function: +-- +-- +mkStreamSpec :: StdStream -> (Maybe Handle -> IO (a, IO ())) -> StreamSpec streamType a + +-- | A stream spec which simply inherits the stream of the parent process. +inherit :: StreamSpec anyStreamType () + +-- | A stream spec which will close the stream for the child process. +closed :: StreamSpec anyStreamType () + +-- | An input stream spec which sets the input to the given +-- ByteString. A separate thread will be forked to write the +-- contents to the child process. +byteStringInput :: ByteString -> StreamSpec STInput () + +-- | Capture the output of a process in a ByteString. +-- +-- This function will fork a separate thread to consume all input from +-- the process, and will only make the results available when the +-- underlying Handle is closed. As this is provided as an +-- STM action, you can either check if the result is available, or +-- block until it's ready. +-- +-- In the event of any exception occurring when reading from the +-- Handle, the result of this function will be a Left value +-- containing a ByteStringOutputException. +byteStringOutput :: StreamSpec STOutput (STM (Either ByteStringOutputException ByteString)) + +-- | Create a new pipe between this process and the child, and return a +-- Handle to communicate with the child. +createPipe :: StreamSpec anyStreamType Handle + +-- | Use the provided Handle for the child process, and when the +-- process exits, do not close it. This is useful if, for example, +-- you want to have multiple processes write to the same log file +-- sequentially. +useHandleOpen :: Handle -> StreamSpec anyStreamType () + +-- | Use the provided Handle for the child process, and when the +-- process exits, close it. If you have no reason to keep the +-- Handle open, you should use this over useHandleOpen. +useHandleClose :: Handle -> StreamSpec anyStreamType () + +-- | Provide input to a process by writing to a conduit. +sink :: MonadIO m => StreamSpec STInput (ConduitM ByteString o m ()) + +-- | Read output from a process by read from a conduit. +source :: MonadIO m => StreamSpec STOutput (ConduitM i ByteString m ()) + +-- | Launch a process based on the given ProcessConfig. You should +-- ensure that you close stopProcess on the result. It's usually +-- better to use one of the functions in this module which ensures +-- stopProcess is called, such as withProcess. +startProcess :: MonadIO m => ProcessConfig stdin stdout stderr -> m (Process stdin stdout stderr) + +-- | Close a process and release any resources acquired. This will ensure +-- terminateProcess is called, wait for the process to actually +-- exit, and then close out resources allocated for the streams. In the +-- event of any cleanup exceptions being thrown, or if a non-success exit +-- code was received and setCheckExitCode was used, this will +-- throw an exception. +stopProcess :: MonadIO m => Process stdin stdout stderr -> m () + +-- | Use the bracket pattern to call startProcess and ensure +-- stopProcess is called. +withProcess :: (MonadIO m, MonadMask m) => ProcessConfig stdin stdout stderr -> (Process stdin stdout stderr -> m a) -> m a + +-- | Run a process, capture its standard output and error as a +-- ByteString, wait for it to complete, and then return its exit +-- code, output, and error. +-- +-- Note that any previously used setStdout or setStderr +-- will be overridden. +readProcess :: MonadIO m => ProcessConfig stdin stdoutIgnored stderrIgnored -> m (ExitCode, ByteString, ByteString) + +-- | Run the given process, wait for it to exit, and returns its +-- ExitCode. +runProcess :: MonadIO m => ProcessConfig stdin stdout stderr -> m ExitCode + +-- | Same as runProcess, but ignores the ExitCode. +runProcess_ :: MonadIO m => ProcessConfig stdin stdout stderr -> m () + +-- | Wait for the process to exit and then return its ExitCode. +waitExitCode :: MonadIO m => Process stdin stdout stderr -> m ExitCode + +-- | Same as waitExitCode, but in STM. +waitExitCodeSTM :: Process stdin stdout stderr -> STM ExitCode + +-- | Check if a process has exited and, if so, return its ExitCode. +checkExitCode :: MonadIO m => Process stdin stdout stderr -> m (Maybe ExitCode) + +-- | Same as checkExitCode, but in STM. +checkExitCodeSTM :: Process stdin stdout stderr -> STM (Maybe ExitCode) + +-- | Get the child's standard input stream value. +getStdin :: Process stdin stdout stderr -> stdin + +-- | Get the child's standard output stream value. +getStdout :: Process stdin stdout stderr -> stdout + +-- | Get the child's standard error stream value. +getStderr :: Process stdin stdout stderr -> stderr + +-- | Exit code generated by stopProcess when setCheckExitCode +-- is True and a process exits with a non-success code. Contains +-- the non-success code, and if any other exceptions occur during +-- cleanup, that exception. +data ExitCodeException +ExitCodeException :: ExitCode -> (Maybe SomeException) -> ExitCodeException + +-- | Wrapper for when an exception is thrown when reading from a child +-- process, used by byteStringOutput. +newtype ByteStringOutputException +ByteStringOutputException :: SomeException -> ByteStringOutputException +instance GHC.Show.Show System.Process.Typed.ByteStringOutputException +instance GHC.Show.Show System.Process.Typed.ExitCodeException +instance GHC.Base.Functor (System.Process.Typed.StreamSpec streamType) +instance GHC.Base.Functor System.Process.Typed.Cleanup +instance (stdin ~ (), stdout ~ (), stderr ~ ()) => Data.String.IsString (System.Process.Typed.ProcessConfig stdin stdout stderr) +instance (streamType ~ 'System.Process.Typed.STInput, res ~ ()) => Data.String.IsString (System.Process.Typed.StreamSpec streamType res) +instance GHC.Base.Applicative System.Process.Typed.Cleanup +instance GHC.Exception.Exception System.Process.Typed.ExitCodeException +instance GHC.Exception.Exception System.Process.Typed.ByteStringOutputException