commit 38bf109bc444b362a2fea385f22ba41bbd44595c
parent bf3e347ce5235dad9eeb585fc84b0b2638c7ef8b
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sat, 26 Aug 2023 07:23:00 +0900
change
Diffstat:
| M | file.go | | | 83 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
| M | server.go | | | 12 | ++++-------- |
| M | testdir/a | | | 0 | |
| A | uid_unix.go | | | 39 | +++++++++++++++++++++++++++++++++++++++ |
4 files changed, 85 insertions(+), 49 deletions(-)
diff --git a/file.go b/file.go
@@ -4,6 +4,7 @@ import (
"fmt"
"io"
"io/fs"
+ "log"
"os"
"path"
"time"
@@ -152,29 +153,28 @@ func (fi *FileInfo) Sys() any { return fi.stat }
func (fi *FileInfo) Qid() *Qid { return fi.Sys().(*stat).qid }
type File struct {
- fs *FS // file system to which this file belongs
+ fs *FS // file system to which this file belongs
file fs.File // underlying file
- path string // absolute path from the root of the fs.
+ path string // absolute path from the root of the fs.
// System-modified data. I don't know how to use.
Type uint16
Dev uint32
// File data
- Qid Qid // unique id from server
// The following data should be derived from fs.Stat()
// every time Stat() is called.
-/*
- Mode FileMode // permissions
- Atime uint32 // last read time
- Mtime uint32 // last write time
- Length int64 // file length
- Name string // last element of path
- Uid string // owner name
- Gid string // group name
- Muid string // last modifier name
-*/
+ /*
+ Mode FileMode // permissions
+ Atime uint32 // last read time
+ Mtime uint32 // last write time
+ Length int64 // file length
+ Name string // last element of path
+ Uid string // owner name
+ Gid string // group name
+ Muid string // last modifier name
+ */
}
type hasQid interface {
@@ -199,27 +199,7 @@ func openFile(fsys *FS, fpath string) (*File, error) {
fs: fsys,
file: file,
path: fpath,
-/*
- Name: path.Base(fpath),
- Mode: fsModeTo9Mode(fsfi.Mode()),
- Atime: uint32(fsfi.ModTime().Unix()),
- Mtime: uint32(fsfi.ModTime().Unix()),
- Length: fsfi.Size(),
- Uid: "kenji", // TODO: use syscall.Stat_t's Uid
- Gid: "kenji",
- Muid: "",
-*/
}
-
- q, ok := fsys.qidPool.lookup(f)
- if !ok {
- q, err = fsys.qidPool.alloc(f)
- if err != nil {
- return nil, fmt.Errorf("alloc qid for file %v: %v", file, err)
- }
- }
- f.Qid = q
-
return f, nil
}
@@ -228,18 +208,38 @@ func (f *File) Stat() (*FileInfo, error) {
if err != nil {
return nil, fmt.Errorf("stat file: %v, %v", f, err)
}
+ qid, err := f.qid()
+ if err != nil {
+ return nil, fmt.Errorf("get qid: %v")
+ }
+ uid, err := f.uid()
+ if err != nil {
+ log.Printf("get uid: %v\n", err)
+ uid = ""
+ }
+ gid, err := f.gid()
+ if err != nil {
+ log.Printf("get gid: %v\n", err)
+ gid = ""
+ }
+ muid, err := f.muid()
+ if err != nil {
+ log.Printf("get muid: %v\n", err)
+ muid = ""
+ }
+
fi := &FileInfo{
info: fsfi,
stat: &stat{
- qid: &f.Qid,
- name: fsfi.Name(),
- mode: fsModeTo9Mode(fsfi.Mode()),
- aTime: uint32(fsfi.ModTime().Unix()),
- mTime: uint32(fsfi.ModTime().Unix()),
+ qid: &qid,
+ name: fsfi.Name(),
+ mode: fsModeTo9Mode(fsfi.Mode()),
+ aTime: uint32(fsfi.ModTime().Unix()),
+ mTime: uint32(fsfi.ModTime().Unix()),
length: fsfi.Size(),
- uid: "", // TODO: uid, gid, muid
- gid: "",
- muid: "",
+ uid: uid, // TODO: uid, gid, muid
+ gid: gid,
+ muid: muid,
},
}
return fi, nil
@@ -299,6 +299,7 @@ func (f *File) ReadDir(n int) ([]*DirEntry, error) {
if err != nil {
return nil, fmt.Errorf("open file: %v", err)
}
+ // BUG: TODO: use fsde.Info()
info, err := file.Stat()
if err != nil {
return nil, fmt.Errorf("stat: %v", err)
diff --git a/server.go b/server.go
@@ -317,20 +317,16 @@ func sRead(s *Server, r *Req) {
if fi.IsDir() {
de, err := fid.File.ReadDir(-1)
if err != nil {
- respond(r, err)
- return
+ log.Printf("read dir: %v", err)
}
for k := int(ifcall.Offset()); k < len(de); k++ {
e := de[k]
info, err := e.Info()
if err != nil {
- respond(r, err)
- return
- }
- st, ok := info.Sys().(*stat)
- if !ok {
- panic("not stat")
+ log.Printf("info: %v", err)
+ continue
}
+ st := info.Sys().(*stat)
buf := st.marshal()
if n+len(buf) > len(data) {
break
diff --git a/testdir/a b/testdir/a
diff --git a/uid_unix.go b/uid_unix.go
@@ -0,0 +1,38 @@
+package lib9p
+
+import (
+ "fmt"
+ "os/user"
+ "strconv"
+ "syscall"
+)
+
+func (f *File) uid() (string, error) {
+ info, err := f.file.Stat()
+ if err != nil {
+ return "", fmt.Errorf("stat %v: %v", f, err)
+ }
+ uid := info.Sys().(*syscall.Stat_t).Uid
+ user, err := user.LookupId(strconv.Itoa(int(uid)))
+ if err != nil {
+ return "", fmt.Errorf("LookupId(%d): %v", uid, err)
+ }
+ return user.Username, nil
+}
+
+func (f *File) gid() (string, error) {
+ info, err := f.file.Stat()
+ if err != nil {
+ return "", fmt.Errorf("stat %v: %v", f, err)
+ }
+ gid := info.Sys().(*syscall.Stat_t).Gid
+ group, err := user.LookupGroupId(strconv.Itoa(int(gid)))
+ if err != nil {
+ return "", fmt.Errorf("LookupGroupId(%d): %v", gid, err)
+ }
+ return group.Name, nil
+}
+
+func (f *File) muid() (string, error) {
+ return "", fmt.Errorf("not implemented on unix")
+}
+\ No newline at end of file