diff options
author | bptato <nincsnevem662@gmail.com> | 2023-06-25 22:53:57 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2023-06-26 00:46:53 +0200 |
commit | d0c4570fffec4c4d9db909f59b7f70c89e012acf (patch) | |
tree | 2657c9686c2854f5cc2a5486a80b88a788b2266d /src/ips/forkserver.nim | |
parent | 0524bed395cfeb467812854c55673c8dc87a1bde (diff) | |
download | chawan-d0c4570fffec4c4d9db909f59b7f70c89e012acf.tar.gz |
Fix crash in openEditor if SIGINT was delivered
nvi for example sets ISIG and traps SIGINT. Without this patch, this would propagate to all processes in the same process group and kill them. (It still does, but we set a signalHandler to ignore that.) Still not perfect, because for some reason we receive WIFSIGNALED even if the signal did not actually kill the editor. For now, we just treat this as a success.
Diffstat (limited to 'src/ips/forkserver.nim')
-rw-r--r-- | src/ips/forkserver.nim | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/ips/forkserver.nim b/src/ips/forkserver.nim index 646d7c39..1a5c2ea0 100644 --- a/src/ips/forkserver.nim +++ b/src/ips/forkserver.nim @@ -60,6 +60,13 @@ proc removeChild*(forkserver: Forkserver, pid: Pid) = forkserver.ostream.swrite(pid) forkserver.ostream.flush() +proc trapSIGINT() = + # trap SIGINT, so e.g. an external editor receiving an interrupt in the + # same process group can't just kill the process + # Note that the main process normally quits on interrupt (thus terminating + # all child processes as well). + setControlCHook(proc() {.noconv.} = discard) + proc forkLoader(ctx: var ForkServerContext, config: LoaderConfig): Pid = var pipefd: array[2, cint] if pipe(pipefd) == -1: @@ -67,6 +74,7 @@ proc forkLoader(ctx: var ForkServerContext, config: LoaderConfig): Pid = let pid = fork() if pid == 0: # child process + trapSIGINT() for i in 0 ..< ctx.children.len: ctx.children[i] = (Pid(0), Pid(0)) ctx.children.setLen(0) zeroMem(addr ctx, sizeof(ctx)) @@ -109,9 +117,11 @@ proc forkBuffer(ctx: var ForkServerContext): Pid = ) ) let pid = fork() - #if pid == -1: - # raise newException(Defect, "Failed to fork process.") + if pid == -1: + raise newException(Defect, "Failed to fork process.") if pid == 0: + # child process + trapSIGINT() for i in 0 ..< ctx.children.len: ctx.children[i] = (Pid(0), Pid(0)) ctx.children.setLen(0) zeroMem(addr ctx, sizeof(ctx)) @@ -191,6 +201,7 @@ proc newForkServer*(): ForkServer = raise newException(Defect, "Failed to fork the fork process.") elif pid == 0: # child process + trapSIGINT() discard close(pipefd_in[1]) # close write discard close(pipefd_out[0]) # close read discard close(pipefd_err[0]) # close read |