From d33fae7946121fc7e7fc7b1a45fc13d129d0256a Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Sat, 18 Jul 2026 17:14:44 +0200 Subject: [PATCH] 9p: fix readDNS to consume result on read (return EOF on second read) Previous implementation returned data forever, causing cat to loop. Now clears the buffer after first read so subsequent reads get EOF. --- server/server.go | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/server/server.go b/server/server.go index f99258c..d106b69 100644 --- a/server/server.go +++ b/server/server.go @@ -760,19 +760,19 @@ func (s *Server) read(cs *connState, fc *plan9.Fcall, ctx context.Context) *plan // /complete: return per-fid result from previous write (offset 0-based) if path == "/complete" { s.log.Debug("Tread path=%q offset=%d count=%d", path, fc.Offset, fc.Count) - return s.readDNS(fc, f.completeResult) + return s.readDNS(fc, &f.completeResult) } // /generate: return per-fid result from previous write (offset 0-based) if path == "/generate" { s.log.Debug("Tread path=%q offset=%d count=%d", path, fc.Offset, fc.Count) - return s.readDNS(fc, f.generateResult) + return s.readDNS(fc, &f.generateResult) } // /route: return per-fid result from previous write (offset 0-based) if path == "/route" { s.log.Debug("Tread path=%q offset=%d count=%d", path, fc.Offset, fc.Count) - return s.readDNS(fc, f.routeResult) + return s.readDNS(fc, &f.routeResult) } s.log.Debug("Tread path=%q offset=%d count=%d", path, fc.Offset, fc.Count) @@ -852,15 +852,16 @@ func (s *Server) readSlice(fc *plan9.Fcall, content []byte) *plan9.Fcall { // readDNS implements the Plan 9 /net/dns read pattern: the result is always // read from offset 0 regardless of the client's file position (which advances -// after a write). This allows write-then-read on the same fd. -func (s *Server) readDNS(fc *plan9.Fcall, content []byte) *plan9.Fcall { +// after a write). Returns the content once, then returns EOF on subsequent reads. +func (s *Server) readDNS(fc *plan9.Fcall, content *[]byte) *plan9.Fcall { var data []byte - if len(content) > 0 { + if len(*content) > 0 { end := int(fc.Count) - if end > len(content) { - end = len(content) + if end > len(*content) { + end = len(*content) } - data = content[:end] + data = (*content)[:end] + *content = nil // consumed; next read returns EOF } return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Count: uint32(len(data)), Data: data} }