about summary refs log tree commit diff stats
path: root/src/display/client.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-09-14 00:58:33 +0200
committerbptato <nincsnevem662@gmail.com>2023-09-14 00:58:33 +0200
commitc2004e4aba182473e79100759a2d58e1bd7d184c (patch)
tree1c3ebe2ee06471053656e7ee7da1fb27a576c691 /src/display/client.nim
parentf4a169ebca315246dd547efce181668d83c73d0b (diff)
downloadchawan-c2004e4aba182473e79100759a2d58e1bd7d184c.tar.gz
Switch buffer -> client connection to client -> buffer
We now connect to buffers from the client, instead of connecting
buffers to the client. This has the following advantages:

* Simplifies the client event loop.
* Makes the client a real client (no more serversocket dependency).
* Slightly more secure, as we no longer have to trust buffers not
  lying about their process ids.
* Facilitates the potential future addition of connections from
  several clients to a single buffer.
Diffstat (limited to 'src/display/client.nim')
-rw-r--r--src/display/client.nim41
1 files changed, 11 insertions, 30 deletions
diff --git a/src/display/client.nim b/src/display/client.nim
index 302cdd4a..3236732d 100644
--- a/src/display/client.nim
+++ b/src/display/client.nim
@@ -31,8 +31,6 @@ import io/promise
 import io/request
 import io/window
 import ips/forkserver
-import ips/serialize
-import ips/serversocket
 import ips/socketstream
 import js/base64
 import js/domexception
@@ -54,8 +52,7 @@ import xhr/xmlhttprequest
 import chakasu/charset
 
 type
-  Client* = ref ClientObj
-  ClientObj* = object
+  Client* = ref object
     alive: bool
     attrs: WindowAttributes
     config {.jsget.}: Config
@@ -75,7 +72,6 @@ type
     precnum: int32 # current number prefix (when vi-numeric-prefix is true)
     s: string # current input buffer
     selector: Selector[Container]
-    ssock: ServerSocket
     store {.jsget, jsset.}: Document
     timeouts: TimeoutState[Container]
     userstyle: CSSStylesheet
@@ -316,26 +312,14 @@ proc acceptBuffers(client: Client) =
     else:
       client.pager.procmap.del(pid)
     stream.close()
-  while client.pager.procmap.len > 0:
-    try:
-      let stream = client.ssock.acceptSocketStream()
-      var pid: Pid
-      #TODO if this returns EAGAIN then we're stuck
-      stream.sread(pid)
-      if pid in client.pager.procmap:
-        let container = client.pager.procmap[pid]
-        client.pager.procmap.del(pid)
-        container.setStream(stream)
-        let fd = stream.source.getFd()
-        client.fdmap[int(fd)] = container
-        client.selector.registerHandle(fd, {Read}, nil)
-        client.pager.handleEvents(container)
-      else:
-        #TODO uh what?
-        client.console.log("???")
-        stream.close()
-    except OSError: # EAGAIN, probably. TODO
-      break
+  for pid, container in client.pager.procmap:
+    let stream = connectSocketStream(pid, buffered = false, blocking = true)
+    container.setStream(stream)
+    let fd = stream.source.getFd()
+    client.fdmap[int(fd)] = container
+    client.selector.registerHandle(fd, {Read}, nil)
+    client.pager.handleEvents(container)
+  client.pager.procmap.clear()
 
 proc c_setvbuf(f: File, buf: pointer, mode: cint, size: csize_t): cint {.
   importc: "setvbuf", header: "<stdio.h>", tags: [].}
@@ -369,8 +353,6 @@ proc handleRead(client: Client, fd: int) =
     client.loader.onRead(fd)
   elif fd in client.loader.unregistered:
     discard # ignore
-  elif fd == client.fd:
-    client.acceptBuffers()
   else:
     let container = client.fdmap[fd]
     client.pager.handleEvent(container)
@@ -430,6 +412,7 @@ proc inputLoop(client: Client) =
         client.console.container.requestLines().then(proc() =
           client.console.container.cursorLastLine())
     client.loader.unregistered.setLen(0)
+    client.acceptBuffers()
     if client.pager.scommand != "":
       client.command(client.pager.scommand)
       client.pager.scommand = ""
@@ -546,10 +529,7 @@ proc launchClient*(client: Client, pages: seq[string],
         dump = not open(tty, "/dev/tty", fmRead)
     else:
       dump = true
-  client.ssock = initServerSocket(false, false)
-  client.fd = int(client.ssock.sock.getFd())
   let selector = newSelector[Container]()
-  selector.registerHandle(client.fd, {Read}, nil)
   let efd = int(client.forkserver.estream.fd)
   selector.registerHandle(efd, {Read}, nil)
   client.loader.registerFun = proc(fd: int) =
@@ -581,6 +561,7 @@ proc launchClient*(client: Client, pages: seq[string],
   for page in pages:
     client.pager.loadURL(page, ctype = contentType, cs = cs)
   client.pager.showAlerts()
+  client.acceptBuffers()
   if not dump:
     client.inputLoop()
   else: