diff options
author | Miran <narimiran@disroot.org> | 2019-02-19 17:25:03 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-02-19 17:25:03 +0100 |
commit | 50d1a46537d952bd3684bf752897f707456b0c3d (patch) | |
tree | 5a8a81a891cd9c5b9a0d940000ecddda8ff01b1a | |
parent | e4a76c6ebf76170b3d3950c0ae0bb4d1e51689f2 (diff) | |
download | Nim-50d1a46537d952bd3684bf752897f707456b0c3d.tar.gz |
better docs: osproc (#10708)
* better docs: osproc * fix a typo in the docs, deprecate "demon"
-rw-r--r-- | lib/pure/osproc.nim | 225 | ||||
-rw-r--r-- | nimsuggest/crashtester.nim | 2 | ||||
-rw-r--r-- | nimsuggest/tester.nim | 4 | ||||
-rw-r--r-- | tests/async/tupcoming_async.nim | 2 | ||||
-rw-r--r-- | tools/vccexe/vcvarsall.nim | 2 |
5 files changed, 164 insertions, 71 deletions
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 9502b679a..19d26f2eb 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -9,6 +9,11 @@ ## This module implements an advanced facility for executing OS processes ## and process communication. +## +## **See also:** +## * `os module <os.html>`_ +## * `streams module <streams.html>`_ +## * `memfiles module <memfiles.html>`_ include "system/inclrtl" @@ -26,22 +31,23 @@ when defined(linux): import linux type - ProcessOption* = enum ## options that can be passed `startProcess` - poEchoCmd, ## echo the command before execution - poUsePath, ## Asks system to search for executable using PATH environment - ## variable. - ## On Windows, this is the default. - poEvalCommand, ## Pass `command` directly to the shell, without quoting. - ## Use it only if `command` comes from trusted source. - poStdErrToStdOut, ## merge stdout and stderr to the stdout stream - poParentStreams, ## use the parent's streams - poInteractive, ## optimize the buffer handling for responsiveness for - ## UI applications. Currently this only affects - ## Windows: Named pipes are used so that you can peek - ## at the process' output streams. - poDemon ## Windows: The program creates no Window. - ## Unix: Start the program as a demon. This is still - ## work in progress! + ProcessOption* = enum ## Options that can be passed to `startProcess proc + ## <#startProcess,string,string,openArray[string],StringTableRef,set[ProcessOption]>`_. + poEchoCmd, ## Echo the command before execution. + poUsePath, ## Asks system to search for executable using PATH environment + ## variable. + ## On Windows, this is the default. + poEvalCommand, ## Pass `command` directly to the shell, without quoting. + ## Use it only if `command` comes from trusted source. + poStdErrToStdOut, ## Merge stdout and stderr to the stdout stream. + poParentStreams, ## Use the parent's streams. + poInteractive, ## Optimize the buffer handling for responsiveness for + ## UI applications. Currently this only affects + ## Windows: Named pipes are used so that you can peek + ## at the process' output streams. + poDaemon ## Windows: The program creates no Window. + ## Unix: Start the program as a daemon. This is still + ## work in progress! ProcessObj = object of RootObj when defined(windows): @@ -57,7 +63,12 @@ type exitFlag: bool options: set[ProcessOption] - Process* = ref ProcessObj ## represents an operating system process + Process* = ref ProcessObj ## Represents an operating system process. + +const poDemon* {.deprecated.} = poDaemon ## Nim versions before 0.20 + ## used the wrong spelling ("demon"). + ## Now `ProcessOption` uses the correct spelling ("daemon"), + ## and this is needed just for backward compatibility. proc execProcess*(command: string, @@ -72,23 +83,41 @@ proc execProcess*(command: string, RootEffect].} ## A convenience procedure that executes ``command`` with ``startProcess`` ## and returns its output as a string. - ## WARNING: this function uses poEvalCommand by default for backward compatibility. + ## + ## **WARNING:** This function uses `poEvalCommand` by default for backward + ## compatibility. ## Make sure to pass options explicitly. ## - ## .. code-block:: Nim + ## See also: + ## * `startProcess proc + ## <#startProcess,string,string,openArray[string],StringTableRef,set[ProcessOption]>`_ + ## * `execProcesses proc <#execProcesses,openArray[string],proc(int),proc(int,Process)>`_ + ## * `execCmd proc <#execCmd,string>`_ + ## + ## Example: ## + ## .. code-block:: Nim ## let outp = execProcess("nim c -r mytestfile.nim") ## # Note: outp may have an interleave of text from the nim compile ## # and any output from mytestfile when it runs proc execCmd*(command: string): int {.rtl, extern: "nosp$1", tags: [ExecIOEffect, ReadIOEffect, RootEffect].} - ## Executes ``command`` and returns its error code. Standard input, output, - ## error streams are inherited from the calling process. This operation - ## is also often called `system`:idx:. + ## Executes ``command`` and returns its error code. ## - ## .. code-block:: Nim + ## Standard input, output, error streams are inherited from the calling process. + ## This operation is also often called `system`:idx:. + ## + ## See also: + ## * `execCmdEx proc <#execCmdEx,string,set[ProcessOption]>`_ + ## * `startProcess proc + ## <#startProcess,string,string,openArray[string],StringTableRef,set[ProcessOption]>`_ + ## * `execProcess proc + ## <#execProcess,string,string,openArray[string],StringTableRef,set[ProcessOption]>`_ + ## + ## Example: ## + ## .. code-block:: Nim ## let errC = execCmd("nim c -r mytestfile.nim") proc startProcess*(command: string, @@ -100,14 +129,16 @@ proc startProcess*(command: string, RootEffect].} ## Starts a process. `Command` is the executable file, `workingDir` is the ## process's working directory. If ``workingDir == ""`` the current directory - ## is used. `args` are the command line arguments that are passed to the + ## is used (default). `args` are the command line arguments that are passed to the ## process. On many operating systems, the first command line argument is the - ## name of the executable. `args` should not contain this argument! + ## name of the executable. `args` should *not* contain this argument! ## `env` is the environment that will be passed to the process. - ## If ``env == nil`` the environment is inherited of + ## If ``env == nil`` (default) the environment is inherited of ## the parent process. `options` are additional flags that may be passed - ## to `startProcess`. See the documentation of ``ProcessOption`` for the - ## meaning of these flags. You need to `close` the process when done. + ## to `startProcess`. See the documentation of `ProcessOption<#ProcessOption>`_ + ## for the meaning of these flags. + ## + ## You need to `close <#close,Process>`_ the process when done. ## ## Note that you can't pass any `args` if you use the option ## ``poEvalCommand``, which invokes the system shell to run the specified @@ -119,102 +150,154 @@ proc startProcess*(command: string, ## ## Return value: The newly created process object. Nil is never returned, ## but ``OSError`` is raised in case of an error. - -proc startCmd*(command: string, options: set[ProcessOption] = { - poStdErrToStdOut, poUsePath}): Process {. - tags: [ExecIOEffect, ReadEnvEffect, RootEffect], deprecated.} = - ## Deprecated - use `startProcess` directly. - result = startProcess(command=command, options=options + {poEvalCommand}) + ## + ## See also: + ## * `execProcesses proc <#execProcesses,openArray[string],proc(int),proc(int,Process)>`_ + ## * `execProcess proc + ## <#execProcess,string,string,openArray[string],StringTableRef,set[ProcessOption]>`_ + ## * `execCmd proc <#execCmd,string>`_ proc close*(p: Process) {.rtl, extern: "nosp$1", tags: [WriteIOEffect].} ## When the process has finished executing, cleanup related handles. ## - ## **Warning:** If the process has not finished executing, this will forcibly + ## **WARNING:** If the process has not finished executing, this will forcibly ## terminate the process. Doing so may result in zombie processes and ## `pty leaks <http://stackoverflow.com/questions/27021641/how-to-fix-request-failed-on-channel-0>`_. proc suspend*(p: Process) {.rtl, extern: "nosp$1", tags: [].} ## Suspends the process `p`. + ## + ## See also: + ## * `resume proc <#resume,Process>`_ + ## * `terminate proc <#terminate,Process>`_ + ## * `kill proc <#kill,Process>`_ + proc resume*(p: Process) {.rtl, extern: "nosp$1", tags: [].} ## Resumes the process `p`. + ## + ## See also: + ## * `suspend proc <#suspend,Process>`_ + ## * `terminate proc <#terminate,Process>`_ + ## * `kill proc <#kill,Process>`_ proc terminate*(p: Process) {.rtl, extern: "nosp$1", tags: [].} - ## Stop the process `p`. On Posix OSes the procedure sends ``SIGTERM`` - ## to the process. On Windows the Win32 API function ``TerminateProcess()`` + ## Stop the process `p`. + ## + ## On Posix OSes the procedure sends ``SIGTERM`` to the process. + ## On Windows the Win32 API function ``TerminateProcess()`` ## is called to stop the process. + ## + ## See also: + ## * `suspend proc <#suspend,Process>`_ + ## * `resume proc <#resume,Process>`_ + ## * `kill proc <#kill,Process>`_ proc kill*(p: Process) {.rtl, extern: "nosp$1", tags: [].} - ## Kill the process `p`. On Posix OSes the procedure sends ``SIGKILL`` to - ## the process. On Windows ``kill()`` is simply an alias for ``terminate()``. + ## Kill the process `p`. + ## + ## On Posix OSes the procedure sends ``SIGKILL`` to the process. + ## On Windows ``kill`` is simply an alias for `terminate() <#terminate,Process>`_. + ## + ## See also: + ## * `suspend proc <#suspend,Process>`_ + ## * `resume proc <#resume,Process>`_ + ## * `terminate proc <#terminate,Process>`_ proc running*(p: Process): bool {.rtl, extern: "nosp$1", tags: [].} ## Returns true iff the process `p` is still running. Returns immediately. proc processID*(p: Process): int {.rtl, extern: "nosp$1".} = - ## returns `p`'s process ID. See also ``os.getCurrentProcessId()``. + ## Returns `p`'s process ID. + ## + ## See also: + ## * `os.getCurrentProcessId proc <os.html#getCurrentProcessId>`_ return p.id proc waitForExit*(p: Process, timeout: int = -1): int {.rtl, extern: "nosp$1", tags: [].} - ## waits for the process to finish and returns `p`'s error code. + ## Waits for the process to finish and returns `p`'s error code. ## - ## **Warning**: Be careful when using waitForExit for processes created without - ## poParentStreams because they may fill output buffers, causing deadlock. + ## **WARNING**: Be careful when using `waitForExit` for processes created without + ## `poParentStreams` because they may fill output buffers, causing deadlock. ## ## On posix, if the process has exited because of a signal, 128 + signal ## number will be returned. proc peekExitCode*(p: Process): int {.rtl, extern: "nosp$1", tags: [].} - ## return -1 if the process is still running. Otherwise the process' exit code + ## Return `-1` if the process is still running. Otherwise the process' exit code. ## ## On posix, if the process has exited because of a signal, 128 + signal ## number will be returned. proc inputStream*(p: Process): Stream {.rtl, extern: "nosp$1", tags: [].} - ## returns ``p``'s input stream for writing to. + ## Returns ``p``'s input stream for writing to. ## - ## **Warning**: The returned `Stream` should not be closed manually as it + ## **WARNING**: The returned `Stream` should not be closed manually as it ## is closed when closing the Process ``p``. + ## + ## See also: + ## * `outputStream proc <#outputStream,Process>`_ + ## * `errorStream proc <#errorStream,Process>`_ proc outputStream*(p: Process): Stream {.rtl, extern: "nosp$1", tags: [].} - ## returns ``p``'s output stream for reading from. + ## Returns ``p``'s output stream for reading from. ## - ## **Warning**: The returned `Stream` should not be closed manually as it + ## **WARNING**: The returned `Stream` should not be closed manually as it ## is closed when closing the Process ``p``. + ## + ## See also: + ## * `inputStream proc <#inputStream,Process>`_ + ## * `errorStream proc <#errorStream,Process>`_ proc errorStream*(p: Process): Stream {.rtl, extern: "nosp$1", tags: [].} - ## returns ``p``'s error stream for reading from. + ## Returns ``p``'s error stream for reading from. ## - ## **Warning**: The returned `Stream` should not be closed manually as it + ## **WARNING**: The returned `Stream` should not be closed manually as it ## is closed when closing the Process ``p``. + ## + ## See also: + ## * `inputStream proc <#inputStream,Process>`_ + ## * `outputStream proc <#outputStream,Process>`_ proc inputHandle*(p: Process): FileHandle {.rtl, extern: "nosp$1", tags: [].} = - ## returns ``p``'s input file handle for writing to. + ## Returns ``p``'s input file handle for writing to. ## - ## **Warning**: The returned `FileHandle` should not be closed manually as + ## **WARNING**: The returned `FileHandle` should not be closed manually as ## it is closed when closing the Process ``p``. + ## + ## See also: + ## * `outputHandle proc <#outputHandle,Process>`_ + ## * `errorHandle proc <#errorHandle,Process>`_ result = p.inHandle proc outputHandle*(p: Process): FileHandle {.rtl, extern: "nosp$1", tags: [].} = - ## returns ``p``'s output file handle for reading from. + ## Returns ``p``'s output file handle for reading from. ## - ## **Warning**: The returned `FileHandle` should not be closed manually as + ## **WARNING**: The returned `FileHandle` should not be closed manually as ## it is closed when closing the Process ``p``. + ## + ## See also: + ## * `inputHandle proc <#inputHandle,Process>`_ + ## * `errorHandle proc <#errorHandle,Process>`_ result = p.outHandle proc errorHandle*(p: Process): FileHandle {.rtl, extern: "nosp$1", tags: [].} = - ## returns ``p``'s error file handle for reading from. + ## Returns ``p``'s error file handle for reading from. ## - ## **Warning**: The returned `FileHandle` should not be closed manually as + ## **WARNING**: The returned `FileHandle` should not be closed manually as ## it is closed when closing the Process ``p``. + ## + ## See also: + ## * `inputHandle proc <#inputHandle,Process>`_ + ## * `outputHandle proc <#outputHandle,Process>`_ result = p.errHandle proc countProcessors*(): int {.rtl, extern: "nosp$1".} = - ## returns the numer of the processors/cores the machine has. + ## Returns the number of the processors/cores the machine has. ## Returns 0 if it cannot be detected. result = cpuinfo.countProcessors() @@ -225,9 +308,11 @@ proc execProcesses*(cmds: openArray[string], afterRunEvent: proc(idx: int, p: Process) = nil): int {.rtl, extern: "nosp$1", tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect].} = - ## executes the commands `cmds` in parallel. Creates `n` processes - ## that execute in parallel. The highest (absolute) return value of all processes - ## is returned. Runs `beforeRunEvent` before running each command. + ## Executes the commands `cmds` in parallel. + ## Creates `n` processes that execute in parallel. + ## + ## The highest (absolute) return value of all processes is returned. + ## Runs `beforeRunEvent` before running each command. assert n > 0 if n > 1: @@ -546,7 +631,7 @@ when defined(Windows) and not defined(useNimRtl): else: newWideCString(e.str, e.len) var wwd = newWideCString(wd) var flags = NORMAL_PRIORITY_CLASS or CREATE_UNICODE_ENVIRONMENT - if poDemon in options: flags = flags or CREATE_NO_WINDOW + if poDaemon in options: flags = flags or CREATE_NO_WINDOW success = winlean.createProcessW(nil, tmp, nil, nil, 1, flags, ee, wwd, si, procInfo) else: @@ -851,12 +936,12 @@ elif not defined(useNimRtl): var mask: Sigset chck sigemptyset(mask) chck posix_spawnattr_setsigmask(attr, mask) - if poDemon in data.options: + if poDaemon in data.options: chck posix_spawnattr_setpgroup(attr, 0'i32) var flags = POSIX_SPAWN_USEVFORK or POSIX_SPAWN_SETSIGMASK - if poDemon in data.options: + if poDaemon in data.options: flags = flags or POSIX_SPAWN_SETPGROUP chck posix_spawnattr_setflags(attr, flags) @@ -1294,12 +1379,21 @@ proc execCmdEx*(command: string, options: set[ProcessOption] = { output: TaintedString, exitCode: int] {.tags: [ExecIOEffect, ReadIOEffect, RootEffect], gcsafe.} = - ## a convenience proc that runs the `command`, grabs all its output and + ## A convenience proc that runs the `command`, grabs all its output and ## exit code and returns both. ## - ## .. code-block:: Nim + ## See also: + ## * `execCmd proc <#execCmd,string>`_ + ## * `startProcess proc + ## <#startProcess,string,string,openArray[string],StringTableRef,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}) var outp = outputStream(p) @@ -1318,4 +1412,3 @@ proc execCmdEx*(command: string, options: set[ProcessOption] = { result[1] = peekExitCode(p) if result[1] != -1: break close(p) - diff --git a/nimsuggest/crashtester.nim b/nimsuggest/crashtester.nim index 4b3ba4026..10fef2b23 100644 --- a/nimsuggest/crashtester.nim +++ b/nimsuggest/crashtester.nim @@ -20,7 +20,7 @@ proc callNimsuggest() = let cl = parseCmdLine("nimsuggest --tester temp000.nim") var p = startProcess(command=cl[0], args=cl[1 .. ^1], options={poStdErrToStdOut, poUsePath, - poInteractive, poDemon}) + poInteractive, poDaemon}) let outp = p.outputStream let inp = p.inputStream var report = "" diff --git a/nimsuggest/tester.nim b/nimsuggest/tester.nim index 1074419a5..21292367b 100644 --- a/nimsuggest/tester.nim +++ b/nimsuggest/tester.nim @@ -251,7 +251,7 @@ proc runEpcTest(filename: string): int = let cl = parseCmdLine(epccmd) var p = startProcess(command=cl[0], args=cl[1 .. ^1], options={poStdErrToStdOut, poUsePath, - poInteractive, poDemon}) + poInteractive, poDaemon}) let outp = p.outputStream let inp = p.inputStream var report = "" @@ -293,7 +293,7 @@ proc runTest(filename: string): int = let cl = parseCmdLine(s.cmd) var p = startProcess(command=cl[0], args=cl[1 .. ^1], options={poStdErrToStdOut, poUsePath, - poInteractive, poDemon}) + poInteractive, poDaemon}) let outp = p.outputStream let inp = p.inputStream var report = "" diff --git a/tests/async/tupcoming_async.nim b/tests/async/tupcoming_async.nim index 0a334709d..1c8271886 100644 --- a/tests/async/tupcoming_async.nim +++ b/tests/async/tupcoming_async.nim @@ -98,7 +98,7 @@ when defined(upcoming): var process = startProcess("ping.exe", "", ["127.0.0.1", "-n", "2", "-w", "100"], nil, {poStdErrToStdOut, poUsePath, poInteractive, - poDemon}) + poDaemon}) else: var process = startProcess("sleep", "", ["1"], nil, {poStdErrToStdOut, poUsePath}) diff --git a/tools/vccexe/vcvarsall.nim b/tools/vccexe/vcvarsall.nim index 81b0fb42b..945fb90a6 100644 --- a/tools/vccexe/vcvarsall.nim +++ b/tools/vccexe/vcvarsall.nim @@ -80,7 +80,7 @@ proc vccVarsAll*(path: string, arch: VccArch = vccarchUnspecified, platform_type # Execute vcvarsall with its command-line arguments # and then execute the SET command to list all environment variables let comSpecExec = "\"$1\" /C \"$2 && SET\"" % [comSpecCmd, vcvarsExec] - var comSpecOpts = {poEvalCommand, poDemon, poStdErrToStdOut} + var comSpecOpts = {poEvalCommand, poDaemon, poStdErrToStdOut} if verbose: comSpecOpts.incl poEchoCmd let comSpecOut = execProcess(comSpecExec, options = comSpecOpts) |