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.
This commit is contained in:
parent
ece6c19fa6
commit
d33fae7946
|
|
@ -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}
|
||||
}
|
||||
|
|
|
|||
Reference in New Issue