Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #9634 don't crash on execCmdEx/readLine when inside gdb/lldb (handle EINTR) #13232

Merged
merged 2 commits into from
Feb 11, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions lib/system/io.nim
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,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):
Expand Down Expand Up @@ -315,8 +316,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
Expand Down