summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/osproc.nim225
-rw-r--r--nimsuggest/crashtester.nim2
-rw-r--r--nimsuggest/tester.nim4
-rw-r--r--tests/async/tupcoming_async.nim2
-rw-r--r--tools/vccexe/vcvarsall.nim2
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)
on: first steps' href='/ahoang/Nim/commit/compiler/lambdalifting.nim?h=devel&id=2633e3fb27f1c55b362bbbfd19388b356add6488'>2633e3fb2 ^
632aece19 ^



560a3bad2 ^
2c4a1dbc0 ^



2633e3fb2 ^
2c4a1dbc0 ^
632aece19 ^











2633e3fb2 ^






2c4a1dbc0 ^




632aece19 ^
2c4a1dbc0 ^
2633e3fb2 ^

2c4a1dbc0 ^
632aece19 ^
2633e3fb2 ^
632aece19 ^


2c4a1dbc0 ^






2633e3fb2 ^
632aece19 ^
2633e3fb2 ^
2c4a1dbc0 ^
2633e3fb2 ^
632aece19 ^
2633e3fb2 ^
632aece19 ^


2633e3fb2 ^

632aece19 ^
2633e3fb2 ^



2c4a1dbc0 ^
2633e3fb2 ^

632aece19 ^
2c4a1dbc0 ^
2633e3fb2 ^
632aece19 ^
2633e3fb2 ^


161f6f722 ^

632aece19 ^

2633e3fb2 ^


632aece19 ^
2633e3fb2 ^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270