func (c *ClientConn) readfile(fc *plan9.Fcall, ref *fileRef) *plan9.Fcall { size, err := c.explorer.Sizeof(ref.Path) if err != nil { return c.unexpectedErr(fc, err) } if size > 0 && fc.Offset >= size { // trying to reading past the end of file. // return count == 0 to signal EOF to client fc.Count = 0 return fc } fc.Data = allocBuffer(min(int(c.iounit), int(fc.Count), int(size))) defer discardBuffer(fc.Data) n, err := c.explorer.Read(fc.Data, fc.Offset, ref.Path) if err == io.EOF { if n == 0 { // returned EOF without reading anything, should return fc.Count = 0 discardBuffer(fc.Data) fc.Data = nil err = nil return fc } else { // was able to read som data from the file, should return the count // but not the error. The next call to read will trigger the EOF err = nil } } if err != nil { return c.unexpectedErr(fc, err) } fc.Count = uint32(n) fc.Data = fc.Data[:fc.Count] return fc }
func (c *ClientConn) readdir(fc *plan9.Fcall, ref *fileRef) *plan9.Fcall { // if the call have an offset, return 0 // since all readdir call's will return the full directory if fc.Offset > 0 { fc.Count = 0 return fc } childs, err := c.explorer.ListDir(ref.Path) if err != nil { return c.unexpectedErr(fc, err) } tmpBuf := allocBuffer(int(c.iounit)) out := bytes.NewBuffer(tmpBuf[:0]) defer discardBuffer(tmpBuf) for _, id := range childs { stat, err := c.explorer.Stat(id.Path) if err != nil { return c.unexpectedErr(fc, err) } dir := plan9.Dir{ Qid: plan9.Qid{Type: uint8(stat.Type), Vers: stat.Version, Path: id.Path}, Mode: plan9.Perm(stat.Mode), Atime: stat.Atime, Mtime: stat.Mtime, Length: stat.Size, Uid: stat.Uname, Gid: stat.Gname, Name: stat.Name, } buf, err := dir.Bytes() if err != nil { return c.unexpectedErr(fc, err) } _, err = out.Write(buf) if err != nil { return c.unexpectedErr(fc, err) } } fc.Count = uint32(len(fc.Data)) fc.Data = out.Bytes() return fc }
func (c *ClientConn) write(fc *plan9.Fcall) *plan9.Fcall { fc.Type = plan9.Rwrite if fref, have := c.fidRef(fc.Fid); have { n, err := c.explorer.Write(fref.Path, fc.Data, fc.Offset) if err != nil { return c.unexpectedErr(fc, err) } fc.Count = uint32(n) return fc } return c.invalidFidErr(fc) }