diff options
author | bptato <nincsnevem662@gmail.com> | 2023-09-23 02:04:42 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2023-09-23 02:04:42 +0200 |
commit | 860a1e77e40469753dbef080ee6fcc24f82dc847 (patch) | |
tree | 2f3abe60c1fe1fb408f7b20da80f2d575199bccf | |
parent | aa8f96765d1ddd85d0273d01cc9524514b6fe21f (diff) | |
download | chawan-860a1e77e40469753dbef080ee6fcc24f82dc847.tar.gz |
buffer: make readFromFd work with pipes
-rw-r--r-- | src/local/container.nim | 9 | ||||
-rw-r--r-- | src/server/buffer.nim | 21 |
2 files changed, 25 insertions, 5 deletions
diff --git a/src/local/container.nim b/src/local/container.nim index d191c6b3..2f4d0044 100644 --- a/src/local/container.nim +++ b/src/local/container.nim @@ -983,7 +983,14 @@ proc setStream*(container: Container, stream: Stream) = container.iface = newBufferInterface(stream) if container.source.t == LOAD_PIPE: container.iface.passFd(container.source.fd).then(proc() = - discard close(container.source.fd)) + discard close(container.source.fd) + if container.source.fd == 0: + # We have just closed stdin. + # Leaving the stdin fileno open to grab is a bad idea. + # (Yes, I've just got bitten by this: dup2(0, 0). Ouch.) + let devnull = open("/dev/null", O_RDONLY) + discard dup2(devnull, 0) + ) stream.flush() container.load() else: diff --git a/src/server/buffer.nim b/src/server/buffer.nim index af735c41..4ab09c20 100644 --- a/src/server/buffer.nim +++ b/src/server/buffer.nim @@ -750,8 +750,8 @@ proc connect2*(buffer: Buffer) {.proxy.} = buffer.selector.registerHandle(buffer.fd, {Read}, 0) proc redirectToFd*(buffer: Buffer, fd: FileHandle, wait: bool) {.proxy.} = - #TODO also clone & fd - if buffer.source.t == LOAD_REQUEST: + case buffer.source.t + of LOAD_REQUEST: let ss = SocketStream(buffer.istream) ss.swrite(true) ss.sendFileHandle(fd) @@ -765,6 +765,20 @@ proc redirectToFd*(buffer: Buffer, fd: FileHandle, wait: bool) {.proxy.} = ss.sread(dummy) discard close(fd) ss.close() + of LOAD_PIPE: + let ps = newPosixStream(fd) + let bfd = cint(buffer.fd) + #TODO make it work without wait + discard fcntl(bfd, F_SETFL, fcntl(bfd, F_GETFL, 0) and not O_NONBLOCK) + var buf: array[4096, uint8] + while not buffer.istream.atEnd: + let n = buffer.istream.readData(addr buf[0], buf.len) + ps.writeData(addr buf[0], n) + ps.close() + buffer.fd = -1 + buffer.istream.close() + of CLONE: + discard proc readFromFd*(buffer: Buffer, fd: FileHandle, ishtml: bool) {.proxy.} = let contentType = if ishtml: @@ -781,8 +795,7 @@ proc readFromFd*(buffer: Buffer, fd: FileHandle, ishtml: bool) {.proxy.} = buffer.contenttype = contentType discard fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) or O_NONBLOCK) let ps = newPosixStream(fd) - buffer.istream = newTeeStream(ps, buffer.sstream, - closedest = false) + buffer.istream = newTeeStream(ps, buffer.sstream, closedest = false) buffer.fd = fd buffer.selector.registerHandle(buffer.fd, {Read}, 0) |