diff options
author | Matt Haggard <haggardii@gmail.com> | 2020-12-18 04:06:13 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-18 10:06:13 +0100 |
commit | 23d23ecb081be6702d74024be8f96d92d9f88a59 (patch) | |
tree | 9e8d6dff07ff798f04106882c99aa871319bddce /lib | |
parent | df17cf5e9e1afae333d9ab755d19d1c9d4d60a0f (diff) | |
download | Nim-23d23ecb081be6702d74024be8f96d92d9f88a59.tar.gz |
Make 'echo' raise IOErrors when appropriate (#16367)
* Make 'echo' raise IOError when fwrite/fflush fail * Fix fwrite return value comparison * Add test for echo raising error and don't fail to release locks in echo * Fix exitcode expectation * Make 'echo' raise IOError on Windows if it fails * Add nimLegacyEchoNoRaise for prior no-IOError echo behavior * Use checkErrMaybe template
Diffstat (limited to 'lib')
-rw-r--r-- | lib/system/io.nim | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/lib/system/io.nim b/lib/system/io.nim index b3e1725b4..22059c0a8 100644 --- a/lib/system/io.nim +++ b/lib/system/io.nim @@ -223,6 +223,9 @@ when defined(windows): # But we cannot call printf directly as the string might contain \0. # So we have to loop over all the sections separated by potential \0s. var i = c_fprintf(f, "%s", s) + if i < 0: + if doRaise: raiseEIO("cannot write string to file") + return while i < s.len: if s[i] == '\0': let w = c_fputc('\0', f) @@ -780,6 +783,13 @@ when declared(stdout): not defined(nintendoswitch) and not defined(freertos) and hostOS != "any" + const echoDoRaise = not defined(nimLegacyEchoNoRaise) # see PR #16366 + + template checkErrMaybe(succeeded: bool): untyped = + if not succeeded: + when echoDoRaise: + checkErr(stdout) + proc echoBinSafe(args: openArray[string]) {.compilerproc.} = when defined(androidNDK): var s = "" @@ -792,20 +802,18 @@ when declared(stdout): proc flockfile(f: File) {.importc, nodecl.} proc funlockfile(f: File) {.importc, nodecl.} flockfile(stdout) + defer: funlockfile(stdout) when defined(windows) and compileOption("threads"): acquireSys echoLock + defer: releaseSys echoLock for s in args: when defined(windows): - writeWindows(stdout, s) + writeWindows(stdout, s, doRaise = echoDoRaise) else: - discard c_fwrite(s.cstring, cast[csize_t](s.len), 1, stdout) + checkErrMaybe(c_fwrite(s.cstring, cast[csize_t](s.len), 1, stdout) == s.len) const linefeed = "\n" - discard c_fwrite(linefeed.cstring, linefeed.len, 1, stdout) - discard c_fflush(stdout) - when stdOutLock: - funlockfile(stdout) - when defined(windows) and compileOption("threads"): - releaseSys echoLock + checkErrMaybe(c_fwrite(linefeed.cstring, linefeed.len, 1, stdout) == linefeed.len) + checkErrMaybe(c_fflush(stdout) == 0) when defined(windows) and not defined(nimscript) and not defined(js): |