commit a2227797d6f22c5f3aa80284b6b982d886413041
parent 08a8945d2b431cc9549bfda368bac1574a2e2b2f
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 13 Sep 2023 10:44:34 +0900
work around...
Diffstat:
| M | diskfs/file.go | | | 80 | +++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------- |
1 file changed, 54 insertions(+), 26 deletions(-)
diff --git a/diskfs/file.go b/diskfs/file.go
@@ -15,10 +15,43 @@ type File struct {
fs *FS // file system to which this file belongs
file *os.File // underlying file
path string // absolute path from the root of the fs.
+ mode lib9p.OpenMode
childEntry []*lib9p.DirEntry
diroff int // directory offset for ReadDir()
}
+func getChildEntry(fsys *FS, dir *os.File) ([]*lib9p.DirEntry, error) {
+ fi, err := dir.Stat()
+ if err != nil {
+ return nil, fmt.Errorf("stat: %v", err)
+ }
+ var childEntry []*lib9p.DirEntry
+ if !fi.IsDir() {
+ return nil, fmt.Errorf("not a directory")
+ }
+
+ de, err := dir.ReadDir(-1)
+ if err != nil {
+ return nil, fmt.Errorf("read dir: %v", err)
+ }
+ childEntry = make([]*lib9p.DirEntry, len(de))
+ for i := 0; i < len(de); i++ {
+ info, err := de[i].Info()
+ if err != nil {
+ return nil, fmt.Errorf("info: %v", err)
+ }
+ // TODO: unix specific
+ sys := info.Sys().(*syscall.Stat_t)
+ id := fileID{
+ device: sys.Dev,
+ inode: sys.Ino,
+ }
+ stat := fiStat(fsys.qidPool, id, info)
+ childEntry[i] = &lib9p.DirEntry{Stat: *stat}
+ }
+ return childEntry, nil
+}
+
func openFile(fsys *FS, fpath string, mode lib9p.OpenMode) (*File, error) {
fsfile, err := fsys.fs.Open(fpath)
if err != nil {
@@ -30,8 +63,13 @@ func openFile(fsys *FS, fpath string, mode lib9p.OpenMode) (*File, error) {
}
var file *os.File
+ var childEntry []*lib9p.DirEntry
if fsfi.IsDir() {
file = fsfile.(*os.File)
+ childEntry, err = getChildEntry(fsys, file)
+ if err != nil {
+ return nil, err
+ }
} else {
var osmode int
switch mode {
@@ -48,35 +86,10 @@ func openFile(fsys *FS, fpath string, mode lib9p.OpenMode) (*File, error) {
}
}
- fi, err := file.Stat()
- if err != nil {
- return nil, fmt.Errorf("stat: %v", err)
- }
- var childEntry []*lib9p.DirEntry
- if fi.IsDir() {
- de, err := file.ReadDir(-1)
- if err != nil {
- return nil, fmt.Errorf("read dir: %v", err)
- }
- childEntry = make([]*lib9p.DirEntry, len(de))
- for i := 0; i < len(de); i++ {
- info, err := de[i].Info()
- if err != nil {
- return nil, fmt.Errorf("info: %v", err)
- }
- // TODO: unix specific
- sys := info.Sys().(*syscall.Stat_t)
- id := fileID{
- device: sys.Dev,
- inode: sys.Ino,
- }
- stat := fiStat(fsys.qidPool, id, info)
- childEntry[i] = &lib9p.DirEntry{Stat: *stat}
- }
- }
f := &File{
fs: fsys,
file: file,
+ mode: mode,
path: fpath,
childEntry: childEntry,
}
@@ -142,6 +155,21 @@ func (f *File) Parent() (lib9p.File, error) {
}
func (f *File) Child() ([]lib9p.File, error) {
+ if err := f.file.Close(); err != nil {
+ return nil, err
+ }
+
+ var err error
+ dir, err := f.fs.fs.Open(f.path)
+ if err != nil {
+ return nil, err
+ }
+ f.file = dir.(*os.File)
+ f.childEntry, err = getChildEntry(f.fs, f.file)
+ if err != nil {
+ return nil, err
+ }
+
files := make([]lib9p.File, len(f.childEntry))
for i := 0; i < len(f.childEntry); i++ {
cpath := path.Join(f.path, f.childEntry[i].Name())