commit 2bbf1a97d3e0f23e87da85cbbdc809e603371461
parent 99310f35f7a64b95f962bafe1b8fccabd4b13260
Author: Matsuda Kenji <info@mtkn.jp>
Date: Tue, 19 Dec 2023 11:36:30 +0900
change fiStat to return error
Diffstat:
4 files changed, 39 insertions(+), 80 deletions(-)
diff --git a/diskfs/file.go b/diskfs/file.go
@@ -82,7 +82,12 @@ func (f *File) ReadDir(n int) ([]fs.DirEntry, error) {
return nil, fmt.Errorf("info: %v", err)
}
id := idFromInfo(f.path, fi)
- de[i] = &lib9p.DirEntry{Stat: *fiStat(f.fs.qidPool, id, fi)}
+ stat, err := fiStat(f.fs.qidPool, id, fi)
+ if err != nil {
+ return nil, fmt.Errorf("fiStat: %v")
+ }
+ de[i] = &lib9p.DirEntry{Stat: *stat}
+
}
return de, nil
}
diff --git a/diskfs/stat_plan9.go b/diskfs/stat_plan9.go
@@ -16,7 +16,7 @@ import (
// fiStat generates lib9p.Stat from the FileInfo.
// It requires QidPool and fileID to fill the Qid field of Stat.
-func fiStat(pool *QidPool, id fileID, info fs.FileInfo) *lib9p.Stat {
+func fiStat(pool *QidPool, id fileID, info fs.FileInfo) (*lib9p.Stat, error) {
dir := info.Sys().(*syscall.Dir)
qid := lib9p.Qid{
Type: lib9p.QidType(dir.Qid.Type),
@@ -35,7 +35,7 @@ func fiStat(pool *QidPool, id fileID, info fs.FileInfo) *lib9p.Stat {
Uid: dir.Uid,
Gid: dir.Gid,
Muid: dir.Muid,
- }
+ }, nil
}
// Stat is real implementation of File.Stat.
@@ -44,7 +44,11 @@ func (f *File) stat() (*lib9p.FileInfo, error) {
if err != nil {
return nil, fmt.Errorf("stat: %v", err)
}
- return &lib9p.FileInfo{Stat: *fiStat(nil, fileID{}, fi)}, nil
+ stat, err := fiStat(nil, fileID{}, fi)
+ if err != nil {
+ return nil, fmt.Errorf("fiStat: %v", err)
+ }
+ return &lib9p.FileInfo{Stat: *stat}, nil
}
// wstat is the real implementation of File.WStat.
diff --git a/diskfs/stat_unix.go b/diskfs/stat_unix.go
@@ -17,7 +17,7 @@ import (
// fiStat generates lib9p.Stat from the FileInfo.
// It requires QidPool and fileID to fill the Qid field of Stat.
-func fiStat(pool *QidPool, id fileID, info fs.FileInfo) *lib9p.Stat {
+func fiStat(pool *QidPool, id fileID, info fs.FileInfo) (*lib9p.Stat, error) {
qid, ok := pool.lookupID(id, info.ModTime())
if !ok {
var err error
@@ -30,14 +30,15 @@ func fiStat(pool *QidPool, id fileID, info fs.FileInfo) *lib9p.Stat {
stat := info.Sys().(*syscall.Stat_t)
usr, err := user.LookupId(strconv.Itoa(int(stat.Uid)))
if err != nil {
- panic(fmt.Errorf("user: %v", err))
+ return nil, fmt.Errorf("user: %v", err)
}
- group, err := user.LookupGroupId(strconv.Itoa(int(stat.Gid)))
- if err != nil {
- // BUG: in OpenBSD, "user: lookup groupid 1000: too many open files"
- panic(fmt.Errorf("group: %v", err))
+ if _, ok := gidCache[id]; !ok {
+ group, err := user.LookupGroupId(strconv.Itoa(int(stat.Gid)))
+ if err != nil {
+ return nil, fmt.Errorf("LookupGroupId(%d): %v", stat.Gid, err)
+ }
+ gidCache[id] = group.Name
}
-
return &lib9p.Stat{
Type: 0,
Dev: 0,
@@ -48,9 +49,9 @@ func fiStat(pool *QidPool, id fileID, info fs.FileInfo) *lib9p.Stat {
Length: stat.Size,
Name: info.Name(),
Uid: usr.Username,
- Gid: group.Name,
+ Gid: gidCache[id],
Muid: "",
- }
+ }, nil
}
var gidCache map[fileID]string
@@ -66,41 +67,15 @@ func (f *File) stat() (*lib9p.FileInfo, error) {
if err != nil {
return nil, fmt.Errorf("stat: %v", err)
}
- var stat lib9p.Stat
- stat.Type = 0
- stat.Dev = 0
- qid, ok := f.fs.qidPool.lookup(f)
- if !ok {
- qid, err = f.fs.qidPool.add(f)
- if err != nil {
- panic(fmt.Errorf("alloc qid: %v", err))
- }
- }
- stat_t := fsfi.Sys().(*syscall.Stat_t)
- stat.Qid = qid
- stat.Length = fsfi.Size()
- stat.Mode = fsfi.Mode()
- stat.Name = fsfi.Name()
- stat.Atime = uint32(stat_t.Atim.Sec)
- stat.Mtime = uint32(stat_t.Mtim.Sec)
- uid := stat_t.Uid
- usr, err := user.LookupId(strconv.Itoa(int(uid)))
+ id, err := f.id()
if err != nil {
- return nil, fmt.Errorf("LookupId(%d): %v", uid, err)
+ return nil, fmt.Errorf("id: %v", err)
}
- stat.Uid = usr.Username
- gid := stat_t.Gid
- fileid := fileID{device: uint64(stat_t.Dev), inode: stat_t.Ino}
- if _, ok := gidCache[fileid]; !ok {
- group, err := user.LookupGroupId(strconv.Itoa(int(gid)))
- if err != nil {
- return nil, fmt.Errorf("LookupGroupId(%d): %v", gid, err)
- }
- gidCache[fileid] = group.Name
+ stat, err := fiStat(f.fs.qidPool, id, fsfi)
+ if err != nil {
+ return nil, fmt.Errorf("fiStat: %v", err)
}
- stat.Gid = gidCache[fileid]
- stat.Muid = ""
- return &lib9p.FileInfo{stat}, nil
+ return &lib9p.FileInfo{*stat}, nil
}
// wstat is the real implementation of File.WStat.
diff --git a/diskfs/stat_windows.go b/diskfs/stat_windows.go
@@ -21,27 +21,26 @@ func fileTimeToUnixTime(t syscall.Filetime) uint32 {
// fiStat generates lib9p.Stat from the FileInfo.
// It requires QidPool and fileID to fill the Qid field of Stat.
-func fiStat(pool *QidPool, id fileID, info fs.FileInfo) *lib9p.Stat {
+func fiStat(pool *QidPool, id fileID, info fs.FileInfo) (*lib9p.Stat, error) {
qid, ok := pool.lookupID(id, info.ModTime())
if !ok {
var err error
qid, err = pool.addID(id, info)
if err != nil {
- panic(fmt.Errorf("allocID: %v", err))
+ return nil, fmt.Errorf("allocID: %v", err)
}
}
-
stat := info.Sys().(*syscall.Win32FileAttributeData)
/*
// TODO: get actual file uid
usr, err := user.LookupId(strconv.Itoa(syscall.Getuid()))
if err != nil {
- panic(fmt.Errorf("user: %v", err))
+ return nil, fmt.Errorf("user: %v", err)
}
// TODO: get actual file gid
group, err := user.LookupGroupId(strconv.Itoa(syscall.Getgid()))
if err != nil {
- panic(fmt.Errorf("group: %v", err))
+ return nil, fmt.Errorf("group: %v", err)
}
*/
return &lib9p.Stat{
@@ -56,7 +55,7 @@ func fiStat(pool *QidPool, id fileID, info fs.FileInfo) *lib9p.Stat {
Uid: "kenji", //usr.Username,
Gid: "kenji", //group.Name,
Muid: "",
- }
+ }, nil
}
var gidCache map[fileID]string
@@ -72,39 +71,15 @@ func (f *File) stat() (*lib9p.FileInfo, error) {
if err != nil {
return nil, fmt.Errorf("stat: %v", err)
}
- var stat lib9p.Stat
- stat.Type = 0
- stat.Dev = 0
- qid, ok := f.fs.qidPool.lookup(f)
- if !ok {
- qid, err = f.fs.qidPool.add(f)
- if err != nil {
- panic(fmt.Errorf("alloc qid: %v", err))
- }
- }
- stat.Qid = qid
- winfs := fsfi.Sys().(*syscall.Win32FileAttributeData)
- stat.Length = fsfi.Size()
- stat.Mode = fsfi.Mode()
- stat.Name = fsfi.Name()
- stat.Atime = fileTimeToUnixTime(winfs.LastAccessTime)
- stat.Mtime = fileTimeToUnixTime(winfs.LastWriteTime)
-/*
- usr, err := user.LookupId(strconv.Itoa(syscall.Getuid()))
+ id, err := f.id()
if err != nil {
- return nil, fmt.Errorf("LookupId: %v", err)
+ return nil, fmt.Errorf("id: %v", err)
}
-*/
- stat.Uid = "kenji" // usr.Username
-/*
- group, err := user.LookupGroupId(strconv.Itoa(syscall.Getgid()))
+ stat, err := fiStat(f.fs.qidPool, id, fsfi)
if err != nil {
- return nil, fmt.Errorf("LookupGroupId: %v", err)
+ return nil, fmt.Errorf("fiStat: %v", err)
}
-*/
- stat.Gid = "kenji" //group.Name
- stat.Muid = ""
- return &lib9p.FileInfo{stat}, nil
+ return &lib9p.FileInfo{*stat}, nil
}
// wstat is the real implementation of File.WStat.