lib9p

Go 9P library.
Log | Files | Refs | LICENSE

commit 48cd056e2a840f80b01fbc881b518df2b49fbef6
parent 5023b5ec4b4cac943383d99a13e853672fbf23d8
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sun, 24 Dec 2023 12:25:05 +0900

add support for the n argument of client.(*File).ReadDir

Diffstat:
Mclient/file.go | 49+++++++++++++++++++++++++++++++++----------------
Mclient/fs.go | 2+-
Mdiskfs/stat_unix.go | 2+-
3 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/client/file.go b/client/file.go @@ -17,6 +17,7 @@ type File struct { qid lib9p.Qid iounit uint32 fs *FS + dirBuf []fs.DirEntry } func (cf *File) Stat() (fs.FileInfo, error) { @@ -88,7 +89,6 @@ func (cf *File) Read(b []byte) (int, error) { } } -// TODO: support n func (cf *File) ReadDir(n int) ([]fs.DirEntry, error) { if cf.qid.Type&lib9p.QTDIR == 0 { return nil, errors.New("not a directory") @@ -96,21 +96,38 @@ func (cf *File) ReadDir(n int) ([]fs.DirEntry, error) { if cf.fid.omode == -1 { return nil, errors.New("not open") } - tag, err := cf.fs.tPool.add() - if err != nil { - return nil, err - } - data, err := cf.fs.c.Read(context.TODO(), tag, cf.fid.fid, cf.fid.offset, cf.iounit) - cf.fs.tPool.delete(tag) - if err != nil { - return nil, err + var ( + de []fs.DirEntry + err error + data []byte + tag uint16 + ) + for n <= 0 || len(cf.dirBuf) < n { + tag, err = cf.fs.tPool.add() + if err != nil { + break + } + data, err = cf.fs.c.Read(context.TODO(), tag, cf.fid.fid, cf.fid.offset, cf.iounit) + cf.fs.tPool.delete(tag) + if err != nil { + break + } else if len(data) == 0 { + err = io.EOF + break + } + cf.fid.offset += uint64(len(data)) + for len(data) > 0 { + st := lib9p.NewStat(data) + data = data[2+st.Size():] + cf.dirBuf = append(cf.dirBuf, &lib9p.FileInfo{Stat: *st}) + } } - cf.fid.offset += uint64(len(data)) - var de []fs.DirEntry - for len(data) > 0 { - st := lib9p.NewStat(data) - data = data[2+st.Size():] - de = append(de, &lib9p.FileInfo{Stat: *st}) + if 0 < n && n <= len(cf.dirBuf) { + de = cf.dirBuf[:n] + cf.dirBuf = cf.dirBuf[n:] + } else { + de = cf.dirBuf + cf.dirBuf = nil } - return de, nil + return de, err } diff --git a/client/fs.go b/client/fs.go @@ -50,7 +50,7 @@ func (fsys *FS) OpenFile(name string, omode lib9p.OpenMode) (lib9p.File, error) return f, nil } -// walkFile walks the file system to the named file name and +// walkFile walks the file system to the file named name and // returns the corresponding file. // returned file is not open. func (fsys *FS) walkFile(name string) (*File, error) { diff --git a/diskfs/stat_unix.go b/diskfs/stat_unix.go @@ -89,7 +89,7 @@ func (f *File) wstat(s *lib9p.Stat) error { } oldStat := fi.Sys().(*lib9p.Stat) if s.Length != oldStat.Length { - if file == nil { + if file == nil { // TODO: what is this? file, err = os.OpenFile(path.Join(f.fs.rootPath, f.path), os.O_RDWR, 0) if err != nil { return err