From 14c3ab69ee8d5499a63ac9af44e37577dd9613f9 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Fri, 22 Nov 2024 22:42:57 +0800 Subject: [PATCH] fix #19600; No error checking on fclose --- changelog.md | 2 ++ compiler/nim.cfg | 1 + lib/std/syncio.nim | 23 +++++++++++++++++++---- tests/config.nims | 1 + 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/changelog.md b/changelog.md index faef6888f495e..0fca13794a626 100644 --- a/changelog.md +++ b/changelog.md @@ -12,6 +12,8 @@ rounding guarantees (via the avoid conflicts with `system.default`, so named argument usage for this parameter like `getOrDefault(..., default = ...)` will have to be changed. +- With `-d:nimPreviewCheckedClose`, the `close` function in the `std/syncio` module now raises an IO exception in case of an error. + ## Standard library additions and changes [//]: # "Additions:" diff --git a/compiler/nim.cfg b/compiler/nim.cfg index 87c35a7110845..215e3bc8382c4 100644 --- a/compiler/nim.cfg +++ b/compiler/nim.cfg @@ -9,6 +9,7 @@ define:nimPreviewCstringConversion define:nimPreviewProcConversion define:nimPreviewRangeDefault define:nimPreviewNonVarDestructor +define:nimPreviewCheckedClose threads:off #import:"$projectpath/testability" diff --git a/lib/std/syncio.nim b/lib/std/syncio.nim index c34a025af5c86..aeb6055de3a9c 100644 --- a/lib/std/syncio.nim +++ b/lib/std/syncio.nim @@ -320,11 +320,26 @@ elif defined(windows): const BufSize = 4000 -proc close*(f: File) {.tags: [], gcsafe, sideEffect.} = +template closeIgnoreError(f: File) = ## Closes the file. if not f.isNil: discard c_fclose(f) + +when defined(nimPreviewCheckedClose): + proc close*(f: File) {.tags: [], gcsafe, sideEffect.} = + ## Closes the file. + ## + ## Raises an IO exception in case of an error. + if not f.isNil: + let x = c_fclose(f) + if x < 0: + checkErr(f) +else: + proc close*(f: File) {.tags: [], gcsafe, sideEffect.} = + ## Closes the file. + closeIgnoreError(f) + proc readChar*(f: File): char {.tags: [ReadIOEffect].} = ## Reads a single character from the stream `f`. Should not be used in ## performance sensitive code. @@ -708,12 +723,12 @@ proc open*(f: var File, filename: string, # be opened. var res {.noinit.}: Stat if c_fstat(getFileHandle(f2), res) >= 0'i32 and modeIsDir(res.st_mode): - close(f2) + closeIgnoreError(f2) return false when not defined(nimInheritHandles) and declared(setInheritable) and NoInheritFlag.len == 0: if not setInheritable(getOsFileHandle(f2), false): - close(f2) + closeIgnoreError(f2) return false result = true @@ -736,7 +751,7 @@ proc reopen*(f: File, filename: string, mode: FileMode = fmRead): bool {. when not defined(nimInheritHandles) and declared(setInheritable) and NoInheritFlag.len == 0: if not setInheritable(getOsFileHandle(f), false): - close(f) + closeIgnoreError(f) return false result = true diff --git a/tests/config.nims b/tests/config.nims index 11a427803574e..808ddbd83df20 100644 --- a/tests/config.nims +++ b/tests/config.nims @@ -37,6 +37,7 @@ switch("define", "nimPreviewJsonutilsHoleyEnum") switch("define", "nimPreviewHashRef") switch("define", "nimPreviewRangeDefault") switch("define", "nimPreviewNonVarDestructor") +switch("define", "nimPreviewCheckedClose") switch("warningAserror", "UnnamedBreak") when not defined(testsConciseTypeMismatch):