diff --git a/server/server.go b/server/server.go index e9f7521..f99258c 100644 --- a/server/server.go +++ b/server/server.go @@ -757,22 +757,22 @@ func (s *Server) read(cs *connState, fc *plan9.Fcall, ctx context.Context) *plan return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Count: uint32(len(data)), Data: data} } - // /complete: return per-fid result from previous write + // /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.readSlice(fc, f.completeResult) + return s.readDNS(fc, f.completeResult) } - // /generate: return per-fid result from previous write + // /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.readSlice(fc, f.generateResult) + return s.readDNS(fc, f.generateResult) } - // /route: return per-fid result from previous write + // /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.readSlice(fc, f.routeResult) + return s.readDNS(fc, f.routeResult) } s.log.Debug("Tread path=%q offset=%d count=%d", path, fc.Offset, fc.Count) @@ -850,6 +850,21 @@ func (s *Server) readSlice(fc *plan9.Fcall, content []byte) *plan9.Fcall { return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Count: uint32(len(data)), Data: data} } +// 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 { + var data []byte + if len(content) > 0 { + end := int(fc.Count) + if end > len(content) { + end = len(content) + } + data = content[:end] + } + return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Count: uint32(len(data)), Data: data} +} + func (s *Server) helpPath() string { return paths.CfgDir() + "/help.md" }