diff options
-rw-r--r-- | lib/system/io.nim | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/lib/system/io.nim b/lib/system/io.nim index 4bbae98b7..7b9a893bb 100644 --- a/lib/system/io.nim +++ b/lib/system/io.nim @@ -145,6 +145,7 @@ proc strerror(errnum: cint): cstring {.importc, header: "<string.h>".} when not defined(NimScript): var errno {.importc, header: "<errno.h>".}: cint ## error variable + EINTR {.importc: "EINTR", header: "<errno.h>".}: cint proc checkErr(f: File) = when not defined(NimScript): @@ -319,8 +320,20 @@ proc readLine*(f: File, line: var TaintedString): bool {.tags: [ReadIOEffect], # fgets doesn't append an \L for i in 0..<sp: line.string[pos+i] = '\L' - var fgetsSuccess = c_fgets(addr line.string[pos], sp.cint, f) != nil - if not fgetsSuccess: checkErr(f) + var fgetsSuccess: bool + while true: + # fixes #9634; this pattern may need to be abstracted as a template if reused; + # likely other io procs need this for correctness. + fgetsSuccess = c_fgets(addr line.string[pos], sp.cint, f) != nil + if fgetsSuccess: break + when not defined(NimScript): + if errno == EINTR: + errno = 0 + c_clearerr(f) + continue + checkErr(f) + break + let m = c_memchr(addr line.string[pos], '\L'.ord, cast[csize_t](sp)) if m != nil: # \l found: Could be our own or the one by fgets, in any case, we're done |