commit 7e647df108e88e1dce78cb57c8830024d13158fb
parent e34e7bd7151fabcdcef72ace3c0dd8754e265b75
Author: Matsuda Kenji <info@mtkn.jp>
Date: Fri, 29 Dec 2023 13:15:40 +0900
change file interface to use *FileInfo instead of fs.FileInfo
Diffstat:
12 files changed, 49 insertions(+), 19 deletions(-)
diff --git a/auth.go b/auth.go
@@ -16,7 +16,7 @@ type AuthFile struct {
R io.Reader
}
-func (af *AuthFile) Stat() (fs.FileInfo, error) {
+func (af *AuthFile) Stat() (*FileInfo, error) {
if af.Qid.Type&QTAUTH == 0 {
panic("QTAUTH bit not set")
}
diff --git a/client/file.go b/client/file.go
@@ -20,7 +20,7 @@ type File struct {
dirBuf []fs.DirEntry
}
-func (cf *File) Stat() (fs.FileInfo, error) {
+func (cf *File) Stat() (*lib9p.FileInfo, error) {
tag, err := cf.fs.tPool.add()
if err != nil {
return nil, err
diff --git a/client/file_test.go b/client/file_test.go
@@ -57,7 +57,6 @@ func TestReadDir(t *testing.T) {
}
func testReadDir(t *testing.T, cfs *FS, tfs *testfs.FS, cwd string) {
- t.Log(cwd)
cf, err := cfs.Open(cwd)
if err != nil {
t.Fatalf("open: %v", err)
@@ -79,7 +78,8 @@ func testReadDir(t *testing.T, cfs *FS, tfs *testfs.FS, cwd string) {
t.Fatalf("open: %v", err)
}
if len(de) != len(tf.(*testfs.File).Children) {
- t.Fatal("number of directory entries does not match.")
+ t.Fatalf("number of directory entries does not match.: %d != %d",
+ len(de), len(tf.(*testfs.File).Children))
}
L:
for _, f := range de {
diff --git a/cmd/numfs/main.go b/cmd/numfs/main.go
@@ -78,7 +78,7 @@ type numFile struct {
func (f *numFile) Fsys() lib9p.FS { return f.fs }
-func (f *numFile) Stat() (fs.FileInfo, error) {
+func (f *numFile) Stat() (*lib9p.FileInfo, error) {
var stat lib9p.Stat
stat.Type = 0
stat.Dev = 0
@@ -159,7 +159,7 @@ func (f *numFile) ReadDir(n int) ([]fs.DirEntry, error) {
if err != nil {
return nil, fmt.Errorf("stat: %v", err)
}
- de[i] = s.(*lib9p.FileInfo)
+ de[i] = s
}
return de, nil
}
diff --git a/cmd/semfs/fs.go b/cmd/semfs/fs.go
@@ -92,7 +92,7 @@ func (fsys *semFS) Remove(name string) error {
return nil
}
-func (root *semFS) Stat() (fs.FileInfo, error) {
+func (root *semFS) Stat() (*lib9p.FileInfo, error) {
t := uint32(time.Now().Unix())
return &lib9p.FileInfo{Stat: lib9p.Stat{
Qid: lib9p.Qid{Type: lib9p.QTDIR, Vers: 0, Path: 0},
@@ -121,7 +121,7 @@ func (root *semFS) ReadDir(n int) ([]fs.DirEntry, error) {
if err != nil {
return nil, err
}
- de = append(de, fi.(*lib9p.FileInfo))
+ de = append(de, fi)
}
return de, nil
}
@@ -173,7 +173,7 @@ func (f *semFile) start(ctx context.Context) {
f.wchan = wchan
}
-func (f *semFile) Stat() (fs.FileInfo, error) {
+func (f *semFile) Stat() (*lib9p.FileInfo, error) {
t := uint32(time.Now().Unix())
return &lib9p.FileInfo{Stat: lib9p.Stat{
Qid: lib9p.Qid{Type: lib9p.QTFILE, Vers: 0, Path: f.path},
diff --git a/diskfs/file.go b/diskfs/file.go
@@ -17,7 +17,7 @@ type File struct {
}
// Stat returns the *lib9p.FileInfo structure describing file.
-func (f *File) Stat() (fs.FileInfo, error) {
+func (f *File) Stat() (*lib9p.FileInfo, error) {
return f.stat()
}
diff --git a/doc.go b/doc.go
@@ -1,2 +1,2 @@
-// 9P2000 implementation.
+// Package lib9p is a 9P2000 library to implement 9P servers.
package lib9p
diff --git a/export_fs.go b/export_fs.go
@@ -2,6 +2,7 @@ package lib9p
import (
"io/fs"
+ "errors"
)
// exportFS is a wrapper of FS to export it as fs.FS.
@@ -10,5 +11,31 @@ type ExportFS struct {
}
func (fsys ExportFS) Open(name string) (fs.File, error) {
- return fsys.OpenFile(name, OREAD)
+ f, err := fsys.OpenFile(name, OREAD)
+ return ExportFile{f}, err
}
+
+type ExportFile struct {
+ f File
+}
+
+func (f ExportFile) Stat() (fs.FileInfo, error) {
+ info, err := f.f.Stat()
+ return fs.FileInfo(info), err
+}
+
+func (f ExportFile) Close() error {
+ return f.f.Close()
+}
+
+func (f ExportFile) Read(p []byte) (n int, err error) {
+ return f.f.Read(p)
+}
+
+func (f ExportFile) ReadDir(n int) ([]fs.DirEntry, error) {
+ d, ok := f.f.(ReadDirFile)
+ if !ok {
+ return nil, errors.New("not a directory")
+ }
+ return d.ReadDir(n)
+}
+\ No newline at end of file
diff --git a/file.go b/file.go
@@ -5,9 +5,11 @@ import (
"io/fs"
)
-// File is an open file.
+// A File is an open file.
+// The interface is identical to that of [fs.File], but the [fs.FileInfo]
+// returned by Stat function must be *FileInfo of this package.
type File interface {
- Stat() (fs.FileInfo, error)
+ Stat() (*FileInfo, error)
Close() error
io.Reader
}
diff --git a/iofs/file.go b/iofs/file.go
@@ -15,7 +15,7 @@ type File struct {
path string // absolute path from the root of the fs.
}
-func (f *File) Stat() (fs.FileInfo, error) {
+func (f *File) Stat() (*lib9p.FileInfo, error) {
fsfile, err := f.fs.fs.Open(f.path)
if err != nil {
return nil, fmt.Errorf("open: %v", err)
diff --git a/server.go b/server.go
@@ -28,7 +28,7 @@ func setError(r *request, err error) {
}
}
-// Server is a 9P server
+// A Server is a 9P server.
type Server struct {
// If true, the server prints the transcript of the 9P session
// to os.Stderr
diff --git a/testfs/fs.go b/testfs/fs.go
@@ -28,7 +28,7 @@ type File struct {
St lib9p.Stat
}
-func (f *File) Stat() (fs.FileInfo, error) {
+func (f *File) Stat() (*lib9p.FileInfo, error) {
return &lib9p.FileInfo{Stat: f.St}, nil
}
@@ -56,8 +56,8 @@ func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
func (f *File) ReadDir(n int) ([]fs.DirEntry, error) {
de := make([]fs.DirEntry, len(f.Children))
for i, c := range f.Children {
- st, _ := c.Stat()
- de[i] = st.(*lib9p.FileInfo)
+ info, _ := c.Stat()
+ de[i] = info
}
return de, nil
}