diff options
author | Timothee Cour <timothee.cour2@gmail.com> | 2020-05-13 04:45:36 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-13 13:45:36 +0200 |
commit | 041ee92bba0ba3f361218eb20ceeeee6eec85f91 (patch) | |
tree | 1a55acb85d5a9d15f836aaa1a0930193bdebf17c /lib/pure | |
parent | 1648f1dd9955c848f8fbaf46a89798ece21460cc (diff) | |
download | Nim-041ee92bba0ba3f361218eb20ceeeee6eec85f91.tar.gz |
`osproc.execCmdEx` now takes an optional `input` for stdin, `env`, workingDir (#14211)
* `osproc.execCmdEx` now takes an optional `input` for stdin * execCmdEx now also takes an optional ``workingDir` and `env`
Diffstat (limited to 'lib/pure')
-rw-r--r-- | lib/pure/osproc.nim | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index f90b310ea..3e3391d52 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -1438,12 +1438,16 @@ elif not defined(useNimRtl): proc execCmdEx*(command: string, options: set[ProcessOption] = { - poStdErrToStdOut, poUsePath}): tuple[ + poStdErrToStdOut, poUsePath}, env: StringTableRef = nil, + workingDir = "", input = ""): tuple[ output: TaintedString, exitCode: int] {.tags: [ExecIOEffect, ReadIOEffect, RootEffect], gcsafe.} = - ## A convenience proc that runs the `command`, grabs all its output and - ## exit code and returns both. + ## A convenience proc that runs the `command`, and returns its `output` and + ## `exitCode`. `env` and `workingDir` params behave as for `startProcess`. + ## If `input.len > 0`, it is passed as stdin. + ## Note: this could block if `input.len` is greater than your OS's maximum + ## pipe buffer size. ## ## See also: ## * `execCmd proc <#execCmd,string>`_ @@ -1452,17 +1456,32 @@ proc execCmdEx*(command: string, options: set[ProcessOption] = { ## * `execProcess proc ## <#execProcess,string,string,openArray[string],StringTableRef,set[ProcessOption]>`_ ## - ## Example: - ## - ## .. code-block:: Nim - ## let (outp, errC) = execCmdEx("nim c -r mytestfile.nim") - - var p = startProcess(command, options = options + {poEvalCommand}) + runnableExamples: + var result = execCmdEx("nim r --hints:off -", options = {}, input = "echo 3*4") + import strutils, strtabs + stripLineEnd(result[0]) ## portable way to remove trailing newline, if any + doAssert result == ("12", 0) + doAssert execCmdEx("ls --nonexistant").exitCode != 0 + when defined(posix): + assert execCmdEx("echo $FO", env = newStringTable({"FO": "B"})) == ("B\n", 0) + assert execCmdEx("echo $PWD", workingDir = "/") == ("/\n", 0) + + when (NimMajor, NimMinor, NimPatch) < (1, 3, 5): + doAssert input.len == 0 + doAssert workingDir.len == 0 + doAssert env == nil + + var p = startProcess(command, options = options + {poEvalCommand}, + workingDir = workingDir, env = env) var outp = outputStream(p) - # There is no way to provide input for the child process - # anymore. Closing it will create EOF on stdin instead of eternal - # blocking. + if input.len > 0: + # There is no way to provide input for the child process + # anymore. Closing it will create EOF on stdin instead of eternal + # blocking. + # Writing in chunks would require a selectors (eg kqueue/epoll) to avoid + # blocking on io. + inputStream(p).write(input) close inputStream(p) result = (TaintedString"", -1) |