lib9p

Go 9P library.
Log | Files | Refs

commit 6589901ae37b7c51764260dc48e1eec9e34b0b67
parent 8fffae3c4fb8bd753629de8519fea5b3b83621b4
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sat, 26 Aug 2023 08:11:47 +0900

implement DiskFile

Diffstat:
Mfid.go | 2+-
Mfile.go | 103+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mfs.go | 2+-
Mqid_unix.go | 17+++++++++--------
Mserver.go | 10+++++-----
Atime_unix.go | 26++++++++++++++++++++++++++
Muid_unix.go | 27++++++++++++++++-----------
7 files changed, 120 insertions(+), 67 deletions(-)

diff --git a/fid.go b/fid.go @@ -19,7 +19,7 @@ const ( // TODO: is the mode should be implemented using interfaces? type Fid struct { Fid uint32 OMode OpenMode /* -1 = not open */ - File *File + File File Uid string Qid *Qid } diff --git a/file.go b/file.go @@ -2,8 +2,8 @@ package lib9p import ( "fmt" - "io" "io/fs" + "io" "log" "os" "path" @@ -25,7 +25,7 @@ const ( AREAD ) -func hasPerm(f *File, uid string, p fs.FileMode) (bool, error) { +func hasPerm(f File, uid string, p fs.FileMode) (bool, error) { fi, err := f.Stat() if err != nil { return false, fmt.Errorf("stat: %v", err) @@ -178,17 +178,25 @@ type DiskFile struct { } type File interface { - Type() uint16 - Dev() uint32 - Qid() Qid - Mode() FileMode - Atime() uint32 - Mtime() uint32 - Length() int64 - Name() string - Uid() string - Gid() string - Muid() string + fs.File + pathName() string + + t() uint16 + dev() uint32 + qid() Qid + mode() FileMode + atime() uint32 + mtime() uint32 + length() int64 + name() string + uid() string + gid() string + muid() string +} + +type ReadDirFile interface { + File + ReadDir(int) ([]*DirEntry, error) } type hasQid interface { @@ -204,12 +212,40 @@ func sameFile(fi0, fi1 fs.FileInfo) bool { return os.SameFile(fi0, fi1) } -func openFile(fsys *FS, fpath string) (*File, error) { +func (f *DiskFile) pathName() string { return f.path } +func (f *DiskFile) t() uint16 { return f.Type } +func (f *DiskFile) dev() uint32 { return f.Dev } +func (f *DiskFile) length() int64 { + fi, err := f.file.Stat() + if err != nil { + log.Printf("stat: %v", err) + return 0 + } + return fi.Size() +} +func (f *DiskFile) mode() FileMode { + fi, err := f.Stat() + if err != nil { + log.Printf("stat: %v", err) + return 0 + } + return fi.Sys().(*stat).mode +} +func (f *DiskFile) name() string { + fi, err := f.Stat() + if err != nil { + log.Printf("stat: %v", err) + return "" + } + return fi.Name() +} + +func openFile(fsys *FS, fpath string) (*DiskFile, error) { file, err := fsys.fs.Open(fpath) if err != nil { return nil, fmt.Errorf("open fs: %v", err) } - f := &File{ + f := &DiskFile{ fs: fsys, file: file, path: fpath, @@ -217,30 +253,15 @@ func openFile(fsys *FS, fpath string) (*File, error) { return f, nil } -func (f *File) Stat() (*FileInfo, error) { +func (f *DiskFile) Stat() (fs.FileInfo, error) { fsfi, err := f.file.Stat() 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 = "" - } + qid := f.qid() + uid := f.uid() + gid := f.gid() + muid := f.muid() fi := &FileInfo{ info: fsfi, @@ -259,15 +280,15 @@ func (f *File) Stat() (*FileInfo, error) { return fi, nil } -func (f *File) Close() error { +func (f *DiskFile) Close() error { return f.file.Close() } -func (f *File) Read(b []byte) (int, error) { +func (f *DiskFile) Read(b []byte) (int, error) { return f.file.Read(b) } -func (f *File) ReadAt(p []byte, off int64) (int, error) { +func (f *DiskFile) ReadAt(p []byte, off int64) (int, error) { if f, ok := f.file.(io.ReaderAt); ok { return f.ReadAt(p, off) } @@ -293,7 +314,7 @@ func (f *File) ReadAt(p []byte, off int64) (int, error) { return file.Read(p) } -func (f *File) ReadDir(n int) ([]*DirEntry, error) { +func (f *DiskFile) ReadDir(n int) ([]*DirEntry, error) { fi, err := f.file.Stat() if err != nil { return nil, fmt.Errorf("stat: %v", err) @@ -320,7 +341,7 @@ func (f *File) ReadDir(n int) ([]*DirEntry, error) { } de[i] = &DirEntry{ dirEnt: fsde[i], - info: info, + info: info.(*FileInfo), file: file, } } @@ -330,7 +351,7 @@ func (f *File) ReadDir(n int) ([]*DirEntry, error) { type DirEntry struct { dirEnt fs.DirEntry // underlying fs.DirEntry info *FileInfo - file *File + file File } func (e *DirEntry) Name() string { return e.dirEnt.Name() } diff --git a/fs.go b/fs.go @@ -11,7 +11,7 @@ type FS struct { qidPool *QidPool } -func (fsys *FS) Open(name string) (*File, error) { +func (fsys *FS) Open(name string) (*DiskFile, error) { file, err := openFile(fsys, name) if err != nil { return nil, fmt.Errorf("openFile(%v, %s): %v", fsys, name, err) diff --git a/qid_unix.go b/qid_unix.go @@ -15,7 +15,7 @@ type QidPool struct { nextQid uint64 } -func (f *File) id() (fileID, error) { +func (f *DiskFile) id() (fileID, error) { fi, err := f.file.Stat() if err != nil { return fileID{}, err @@ -28,16 +28,17 @@ func (f *File) id() (fileID, error) { return id, nil } -func (f *File) qid() (Qid, error) { +func (f *DiskFile) qid() Qid { qid, ok := f.fs.qidPool.lookup(f) if ok { - return qid, nil + return qid } qid, err := f.fs.qidPool.alloc(f) if err != nil { - return Qid{}, fmt.Errorf("alloc qid: %v", err) + panic(fmt.Errorf("alloc qid: %v", err)) + return Qid{} } - return qid, nil + return qid } func allocQidPool() *QidPool { @@ -46,7 +47,7 @@ func allocQidPool() *QidPool { } } -func (pool *QidPool) lookup(f *File) (Qid, bool) { +func (pool *QidPool) lookup(f *DiskFile) (Qid, bool) { id, err := f.id() if err != nil { return Qid{}, false @@ -55,7 +56,7 @@ func (pool *QidPool) lookup(f *File) (Qid, bool) { return qid, ok } -func (pool *QidPool) alloc(f *File) (Qid, error) { +func (pool *QidPool) alloc(f *DiskFile) (Qid, error) { id, err := f.id() if err != nil { return Qid{}, fmt.Errorf("get id: %v", err) @@ -73,7 +74,7 @@ func (pool *QidPool) alloc(f *File) (Qid, error) { return qid, nil } -func (pool *QidPool) delete(f *File) { +func (pool *QidPool) delete(f *DiskFile) { id, err := f.id() if err != nil { return diff --git a/server.go b/server.go @@ -179,7 +179,7 @@ func sWalk(s *Server, r *Req) { return } - wqids, err := s.fs.walk(oldFid.File.path, ifcall.WName()) + wqids, err := s.fs.walk(oldFid.File.pathName(), ifcall.WName()) if err != nil { s.fPool.delete(ifcall.NewFid()) log.Printf("walk fs: %v", err) @@ -188,7 +188,7 @@ func sWalk(s *Server, r *Req) { } relPath := path.Join(ifcall.WName()...) - absPath := path.Join(oldFid.File.path, relPath) + absPath := path.Join(oldFid.File.pathName(), relPath) newFid.File, err = s.fs.Open(absPath) if err != nil { log.Printf("open root dir: %v", err) @@ -315,7 +315,7 @@ func sRead(s *Server, r *Req) { return } if fi.IsDir() { - de, err := fid.File.ReadDir(-1) + de, err := fid.File.(ReadDirFile).ReadDir(-1) if err != nil { log.Printf("read dir: %v", err) } @@ -337,7 +337,7 @@ func sRead(s *Server, r *Req) { n += len(buf) } } else { - n, err = fid.File.ReadAt(data, int64(ifcall.Offset())) + n, err = fid.File.(io.ReaderAt).ReadAt(data, int64(ifcall.Offset())) if err != io.EOF && err != nil { log.Printf("sRead: %v\n", err) respond(r, err) @@ -395,7 +395,7 @@ func sStat(s *Server, r *Req) { ofcall := &RStat{ tag: ifcall.Tag(), - info: fileInfo, + info: fileInfo.(*FileInfo), } r.ofcall = ofcall diff --git a/time_unix.go b/time_unix.go @@ -0,0 +1,26 @@ +package lib9p + +import ( + "log" + "syscall" +) + +func (f *DiskFile) atime() uint32 { + fi, err := f.file.Stat() + if err != nil { + log.Printf("stat error: %v", err) + return 0 // TODO: error check? + } + sys := fi.Sys() + return uint32(sys.(syscall.Stat_t).Atim.Sec) +} + +func (f *DiskFile) mtime() uint32 { + fi, err := f.file.Stat() + if err != nil { + log.Printf("stat error: %v", err) + return 0 // TODO: error check? + } + sys := fi.Sys() + return uint32(sys.(syscall.Stat_t).Mtim.Sec) +} diff --git a/uid_unix.go b/uid_unix.go @@ -1,38 +1,43 @@ package lib9p import ( - "fmt" + "log" "os/user" "strconv" "syscall" ) -func (f *File) uid() (string, error) { +func (f *DiskFile) uid() string { info, err := f.file.Stat() if err != nil { - return "", fmt.Errorf("stat %v: %v", f, err) + log.Printf("stat %v: %v", f, err) + return "" } 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) + log.Printf("LookupId(%d): %v", uid, err) + return "" } - return user.Username, nil + return user.Username } -func (f *File) gid() (string, error) { +func (f *DiskFile) gid() string { info, err := f.file.Stat() if err != nil { - return "", fmt.Errorf("stat %v: %v", f, err) + log.Printf("stat %v: %v", f, err) + return "" } 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) + log.Printf("LookupGroupId(%d): %v", gid, err) + return "" } - return group.Name, nil + return group.Name } -func (f *File) muid() (string, error) { - return "", fmt.Errorf("not implemented on unix") +func (f *DiskFile) muid() string { + log.Printf("muid not implemented") + return "" } \ No newline at end of file