diff options
author | bptato <nincsnevem662@gmail.com> | 2025-02-11 16:17:09 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2025-02-26 19:58:08 +0100 |
commit | 55ffd92756faa3b60e3472404025a18509e0fce2 (patch) | |
tree | 5ce18a089ad3c657a3270000d01f64f7b5717b6a /src/local | |
parent | 7ba1c5de335468f77d891b31ab5d0536f1addd25 (diff) | |
download | chawan-55ffd92756faa3b60e3472404025a18509e0fce2.tar.gz |
dynstream: remove exceptions
Now we just pass down the value of n and check errno, plus readDataLoop/writeDataLoop returns a bool indicating whether it failed. For now this seems to work OK, but maybe I'll add a better abstraction in the future. EOFError is still used for handling failed packets; this is brittle, and should be replaced once we have a proper buffering mechanism for them. (That will also let us kill BufStream.) Unrelated: this also fixes a bug in buffer with cacheId.
Diffstat (limited to 'src/local')
-rw-r--r-- | src/local/container.nim | 24 | ||||
-rw-r--r-- | src/local/pager.nim | 73 | ||||
-rw-r--r-- | src/local/term.nim | 14 |
3 files changed, 60 insertions, 51 deletions
diff --git a/src/local/container.nim b/src/local/container.nim index 0039197d..980e95bc 100644 --- a/src/local/container.nim +++ b/src/local/container.nim @@ -1596,7 +1596,7 @@ proc readCanceled*(container: Container) = proc readSuccess*(container: Container; s: string; fd: cint = -1) = let p = container.iface.readSuccess(s, fd != -1) if fd != -1: - container.iface.stream.sflush() + doAssert container.iface.stream.flush() container.iface.stream.source.withPacketWriter w: w.sendAux.add(fd) p.then(proc(res: Request) = @@ -1707,11 +1707,14 @@ func hoverImage(container: Container): string {.jsfget.} = func hoverCachedImage(container: Container): string {.jsfget.} = return container.hoverText[htCachedImage] -proc handleCommand(container: Container) = +# Returns false on I/O error. +proc handleCommand(container: Container): bool = var packet {.noinit.}: array[3, int] # 0 len, 1 auxLen, 2 packetid - container.iface.stream.recvDataLoop(addr packet[0], sizeof(packet)) + if not container.iface.stream.readDataLoop(addr packet[0], sizeof(packet)): + return false assert packet[1] == 0 # no ancillary data possible for BufStream container.iface.resolve(packet[2], packet[0] - sizeof(packet[2]), packet[1]) + return true proc startLoad(container: Container) = if container.config.headless == hmFalse: @@ -1755,7 +1758,9 @@ proc onReadLine(container: Container; w: Slice[int]; return newResolvedPromise() # Synchronously read all lines in the buffer. -proc readLines*(container: Container; handle: proc(line: SimpleFlexibleLine)) = +# Returns false on I/O error. +proc readLines*(container: Container; handle: proc(line: SimpleFlexibleLine)): + bool = # load succeded let w = 0 .. 23 container.iface.getLines(w).then(proc(res: GetLinesResult): EmptyPromise = @@ -1772,7 +1777,9 @@ proc readLines*(container: Container; handle: proc(line: SimpleFlexibleLine)) = ) while container.iface.hasPromises: # fulfill all promises - container.handleCommand() + if not container.handleCommand(): + return false + return true proc drawLines*(container: Container; display: var FixedGrid; hlcolor: CellColor) = let bgcolor = container.bgcolor @@ -1864,11 +1871,14 @@ func findCachedImage*(container: Container; image: PosBitmap; return it return nil -proc handleEvent*(container: Container) = - container.handleCommand() +# Returns false on I/O error. +proc handleEvent*(container: Container): bool = + if not container.handleCommand(): + return false if container.needslines: container.requestLines() container.needslines = false + return true proc addContainerModule*(ctx: JSContext) = ctx.registerType(Highlight) diff --git a/src/local/pager.nim b/src/local/pager.nim index 457cde8d..ca067c3d 100644 --- a/src/local/pager.nim +++ b/src/local/pager.nim @@ -968,9 +968,9 @@ proc drawBufferAdvance(s: openArray[char]; bgcolor: CellColor; oi, ox: var int; ox = x return move(ls) -proc drawBuffer*(pager: Pager; container: Container; ofile: File) = +proc drawBuffer*(pager: Pager; container: Container; ofile: File): bool = var format = Format() - container.readLines(proc(line: SimpleFlexibleLine) = + let res = container.readLines(proc(line: SimpleFlexibleLine) = var x = 0 var w = -1 var i = 0 @@ -997,6 +997,7 @@ proc drawBuffer*(pager: Pager; container: Container; ofile: File) = ofile.writeLine(s) ) ofile.flushFile() + res proc redraw(pager: Pager) {.jsfunc.} = pager.term.clearCanvas() @@ -2431,10 +2432,13 @@ proc writeToFile(istream: PosixStream; outpath: string): bool = return false var buffer {.noinit.}: array[4096, uint8] while true: - let n = istream.recvData(buffer) + let n = istream.readData(buffer) + if n < 0: + return false if n == 0: break - ps.sendDataLoop(buffer.toOpenArray(0, n - 1)) + if not ps.writeDataLoop(buffer.toOpenArray(0, n - 1)): + break ps.sclose() true @@ -3020,8 +3024,7 @@ proc openMenu(pager: Pager; x = -1; y = -1) {.jsfunc.} = pager.menu = newSelect(options, -1, x, y, pager.bufWidth, pager.bufHeight, menuFinish, pager) -proc handleEvent0(pager: Pager; container: Container; event: ContainerEvent): - bool = +proc handleEvent0(pager: Pager; container: Container; event: ContainerEvent) = case event.t of cetLoaded: dec pager.numload @@ -3101,23 +3104,18 @@ proc handleEvent0(pager: Pager; container: Container; event: ContainerEvent): pager.refreshAllowed.incl($url) pager.metaRefresh(container, n, url) ) - return true proc handleEvents(pager: Pager; container: Container) = while (let event = container.popEvent(); event != nil): - if not pager.handleEvent0(container, event): - break + pager.handleEvent0(container, event) proc handleEvents(pager: Pager) = if pager.container != nil: pager.handleEvents(pager.container) proc handleEvent(pager: Pager; container: Container) = - try: - container.handleEvent() + if container.handleEvent(): pager.handleEvents(container) - except IOError: - discard proc runCommand(pager: Pager) = if pager.scommand != "": @@ -3152,30 +3150,27 @@ proc handleStderr(pager: Pager) = let estream = pager.forkserver.estream var hadlf = true while true: - try: - let n = estream.recvData(buffer) - if n == 0: - break - var i = 0 - while i < n: - var j = n - var found = false - for k in i ..< n: - if buffer[k] == '\n': - j = k + 1 - found = true - break - if hadlf: - pager.console.err.write(prefix) - if j - i > 0: - pager.console.err.write(buffer.toOpenArray(i, j - 1)) - i = j - hadlf = found - except ErrorAgain: + let n = estream.readData(buffer) + if n <= 0: break + var i = 0 + while i < n: + var j = n + var found = false + for k in i ..< n: + if buffer[k] == '\n': + j = k + 1 + found = true + break + if hadlf: + pager.console.err.write(prefix) + if j - i > 0: + pager.console.err.write(buffer.toOpenArray(i, j - 1)) + i = j + hadlf = found if not hadlf: pager.console.err.write('\n') - pager.console.err.sflush() + discard pager.console.err.flush() proc handleRead(pager: Pager; fd: int) = if pager.term.istream != nil and fd == pager.term.istream.fd: @@ -3250,10 +3245,7 @@ proc setupSigwinch(pager: Pager): PosixStream = gwriter = writer onSignal SIGWINCH: discard sig - try: - gwriter.sendDataLoop([0u8]) - except ErrorAgain: - discard + discard gwriter.writeData([0u8]) let reader = newPosixStream(pipefd[0]) reader.setCloseOnExec() reader.setBlocking(false) @@ -3333,10 +3325,9 @@ proc headlessLoop(pager: Pager) = proc dumpBuffers(pager: Pager) = pager.headlessLoop() for container in pager.containers: - try: - pager.drawBuffer(container, stdout) + if pager.drawBuffer(container, stdout): pager.handleEvents(container) - except IOError: + else: pager.console.error("Error in buffer", $container.url) # check for errors pager.handleRead(pager.forkserver.estream.fd) diff --git a/src/local/term.nim b/src/local/term.nim index 3aff214d..236599f2 100644 --- a/src/local/term.nim +++ b/src/local/term.nim @@ -245,9 +245,14 @@ when TermcapFound: func cap(term: Terminal; c: TermcapCap): lent string = return term.tc.caps[c] +proc write0(term: Terminal; buffer: openArray[char]) = + if not term.ostream.writeDataLoop(buffer): + stderr.writeLine("Error writing to stdout") + quit(1) + proc flush*(term: Terminal) = if term.obufLen > 0: - term.ostream.sendDataLoop(term.obuf.toOpenArray(0, term.obufLen - 1)) + term.write0(term.obuf.toOpenArray(0, term.obufLen - 1)) term.obufLen = 0 proc write(term: Terminal; s: openArray[char]) = @@ -255,7 +260,7 @@ proc write(term: Terminal; s: openArray[char]) = if s.len + term.obufLen > term.obuf.len: term.flush() if s.len > term.obuf.len: - term.ostream.sendDataLoop(s) + term.write0(s) else: copyMem(addr term.obuf[term.obufLen], unsafeAddr s[0], s.len) term.obufLen += s.len @@ -263,7 +268,10 @@ proc write(term: Terminal; s: openArray[char]) = proc readChar*(term: Terminal): char = if term.ibufn == term.ibufLen: term.ibufn = 0 - term.ibufLen = term.istream.recvData(term.ibuf) + term.ibufLen = term.istream.readData(term.ibuf) + if term.ibufLen == -1: + stderr.writeLine("Error reading from stdin") + quit(1) result = term.ibuf[term.ibufn] inc term.ibufn |