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:
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