mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 14:00:35 +00:00
fix a critical bug in windows.osproc leading to resource leaks and blocking IO [backport] (#14296)
(cherry picked from commit d11cb9d495)
This commit is contained in:
28
changelog.md
28
changelog.md
@@ -50,6 +50,34 @@
|
||||
- `paramCount` & `paramStr` are now defined in os.nim instead of nimscript.nim for nimscript/nimble.
|
||||
- `dollars.$` now works for unsigned ints with `nim js`
|
||||
|
||||
- Improvements to the `bitops` module, including bitslices, non-mutating versions
|
||||
of the original masking functions, `mask`/`masked`, and varargs support for
|
||||
`bitand`, `bitor`, and `bitxor`.
|
||||
|
||||
- `sugar.=>` and `sugar.->` changes: Previously `(x, y: int)` was transformed
|
||||
into `(x: auto, y: int)`, it now becomes `(x: int, y: int)` in consistency
|
||||
with regular proc definitions (although you cannot use semicolons).
|
||||
|
||||
Pragmas and using a name are now allowed on the lefthand side of `=>`. Here
|
||||
is an aggregate example of these changes:
|
||||
```nim
|
||||
import sugar
|
||||
|
||||
foo(x, y: int) {.noSideEffect.} => x + y
|
||||
|
||||
# is transformed into
|
||||
|
||||
proc foo(x: int, y: int): auto {.noSideEffect.} = x + y
|
||||
```
|
||||
- The fields of `times.DateTime` are now private, and are accessed with getters and deprecated setters.
|
||||
|
||||
- The `times` module now handles the default value for `DateTime` more consistently. Most procs raise an assertion error when given
|
||||
an uninitialized `DateTime`, the exceptions are `==` and `$` (which returns `"Uninitialized DateTime"`). The proc `times.isInitialized`
|
||||
has been added which can be used to check if a `DateTime` has been initialized.
|
||||
|
||||
- Fix a bug where calling `close` on io streams in osproc.startProcess was a noop and led to
|
||||
hangs if a process had both reads from stdin and writes (eg to stdout).
|
||||
|
||||
## Language changes
|
||||
|
||||
|
||||
|
||||
@@ -441,7 +441,11 @@ when defined(Windows) and not defined(useNimRtl):
|
||||
handle: Handle
|
||||
atTheEnd: bool
|
||||
|
||||
proc hsClose(s: Stream) = discard # nothing to do here
|
||||
proc hsClose(s: Stream) =
|
||||
# xxx here + elsewhere: check instead of discard; ignoring errors leads to
|
||||
# hard to track bugs
|
||||
discard FileHandleStream(s).handle.closeHandle
|
||||
|
||||
proc hsAtEnd(s: Stream): bool = return FileHandleStream(s).atTheEnd
|
||||
|
||||
proc hsReadData(s: Stream, buffer: pointer, bufLen: int): int =
|
||||
|
||||
@@ -31,6 +31,8 @@ type
|
||||
ULONG* = int32
|
||||
PULONG* = ptr int
|
||||
WINBOOL* = int32
|
||||
## `WINBOOL` uses opposite convention as posix, !=0 meaning success.
|
||||
# xxx this should be distinct int32, distinct would make code less error prone
|
||||
DWORD* = int32
|
||||
PDWORD* = ptr DWORD
|
||||
LPINT* = ptr int32
|
||||
|
||||
@@ -93,3 +93,29 @@ else:
|
||||
removeFile(exePath)
|
||||
except OSError:
|
||||
discard
|
||||
|
||||
import std/streams
|
||||
block: # test for startProcess (more tests needed)
|
||||
# bugfix: windows stdin.close was a noop and led to blocking reads
|
||||
proc startProcessTest(command: string, options: set[ProcessOption] = {
|
||||
poStdErrToStdOut, poUsePath}, input = ""): tuple[
|
||||
output: TaintedString,
|
||||
exitCode: int] {.tags:
|
||||
[ExecIOEffect, ReadIOEffect, RootEffect], gcsafe.} =
|
||||
var p = startProcess(command, options = options + {poEvalCommand})
|
||||
var outp = outputStream(p)
|
||||
if input.len > 0: inputStream(p).write(input)
|
||||
close inputStream(p)
|
||||
result = (TaintedString"", -1)
|
||||
var line = newStringOfCap(120).TaintedString
|
||||
while true:
|
||||
if outp.readLine(line):
|
||||
result[0].string.add(line.string)
|
||||
result[0].string.add("\n")
|
||||
else:
|
||||
result[1] = peekExitCode(p)
|
||||
if result[1] != -1: break
|
||||
close(p)
|
||||
|
||||
var result = startProcessTest("nim r --hints:off -", options = {}, input = "echo 3*4")
|
||||
doAssert result == ("12\n", 0)
|
||||
|
||||
Reference in New Issue
Block a user