about summary refs log tree commit diff stats
path: root/src/ips
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-01-04 01:18:59 +0100
committerbptato <nincsnevem662@gmail.com>2023-01-04 01:18:59 +0100
commit181ea25b5626c697cc9b6bd3e42c85ea920be0f3 (patch)
tree92338bdbf5743ac2e5c383b6abe13ec3518ed433 /src/ips
parenteda263319d5f6b4f7392398a42d67f04056c23e1 (diff)
downloadchawan-181ea25b5626c697cc9b6bd3e42c85ea920be0f3.tar.gz
client, pager, dom, ...: better error handling
Now the browser shouldn't completely die when a buffer crashes.
Diffstat (limited to 'src/ips')
-rw-r--r--src/ips/forkserver.nim26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/ips/forkserver.nim b/src/ips/forkserver.nim
index 906d60a4..85b4aae5 100644
--- a/src/ips/forkserver.nim
+++ b/src/ips/forkserver.nim
@@ -25,6 +25,7 @@ type
     process*: Pid
     istream*: Stream
     ostream*: Stream
+    estream*: PosixStream
 
   ForkServerContext = object
     istream: Stream
@@ -97,10 +98,14 @@ proc forkBuffer(ctx: var ForkServerContext): Pid =
     )
   )
   let pid = fork()
+  #if pid == -1:
+  #  raise newException(Defect, "Failed to fork process.")
   if pid == 0:
     for i in 0 ..< ctx.children.len: ctx.children[i] = (Pid(0), Pid(0))
     ctx.children.setLen(0)
     zeroMem(addr ctx, sizeof(ctx))
+    discard close(stdin.getFileHandle())
+    discard close(stdout.getFileHandle())
     launchBuffer(config, source, attrs, loader, mainproc)
     assert false
   ctx.children.add((pid, loader.process))
@@ -152,34 +157,45 @@ proc runForkServer() =
 
 proc newForkServer*(): ForkServer =
   new(result)
-  var pipefd_in: array[2, cint]
-  var pipefd_out: array[2, cint]
+  var pipefd_in: array[2, cint] # stdin in forkserver
+  var pipefd_out: array[2, cint] # stdout in forkserver
+  var pipefd_err: array[2, cint] # stderr in forkserver
   if pipe(pipefd_in) == -1:
     raise newException(Defect, "Failed to open input pipe.")
   if pipe(pipefd_out) == -1:
     raise newException(Defect, "Failed to open output pipe.")
+  if pipe(pipefd_err) == -1:
+    raise newException(Defect, "Failed to open error pipe.")
   let pid = fork()
   if pid == -1:
     raise newException(Defect, "Failed to fork the fork process.")
   elif pid == 0:
     # child process
-    let readfd = pipefd_in[0]
     discard close(pipefd_in[1]) # close write
-    let writefd = pipefd_out[1]
     discard close(pipefd_out[0]) # close read
+    discard close(pipefd_err[0]) # close read
+    let readfd = pipefd_in[0]
+    let writefd = pipefd_out[1]
+    let errfd = pipefd_err[1]
     discard dup2(readfd, stdin.getFileHandle())
     discard dup2(writefd, stdout.getFileHandle())
+    discard dup2(errfd, stderr.getFileHandle())
+    stderr.flushFile()
     discard close(pipefd_in[0])
     discard close(pipefd_out[1])
+    discard close(pipefd_err[1])
     runForkServer()
     assert false
   else:
     discard close(pipefd_in[0]) # close read
     discard close(pipefd_out[1]) # close write
-    var readf, writef: File
+    discard close(pipefd_err[1]) # close write
+    var writef, readf: File
     if not open(writef, pipefd_in[1], fmWrite):
       raise newException(Defect, "Failed to open output handle")
     if not open(readf, pipefd_out[0], fmRead):
       raise newException(Defect, "Failed to open input handle")
     result.ostream = newFileStream(writef)
     result.istream = newFileStream(readf)
+    result.estream = newPosixStream(pipefd_err[0])
+    discard fcntl(pipefd_err[0], F_SETFL, fcntl(pipefd_err[0], F_GETFL, 0) or O_NONBLOCK)