lib9p

Go 9P library.
Log | Files | Refs

commit 497a942661c9113976dd5db8df9d0e31aa3fb96a
parent 6589901ae37b7c51764260dc48e1eec9e34b0b67
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sat, 26 Aug 2023 10:00:44 +0900

split functions

Diffstat:
Ddisk.go | 2--
Adisk_unix.go | 138+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mfile.go | 149-------------------------------------------------------------------------------
Mfs.go | 2+-
Mqid_unix.go | 14+++++++-------
Mserver.go | 30++++++++++++------------------
6 files changed, 158 insertions(+), 177 deletions(-)

diff --git a/disk.go b/disk.go @@ -1,2 +0,0 @@ -package lib9p - diff --git a/disk_unix.go b/disk_unix.go @@ -0,0 +1,138 @@ +package lib9p + +import ( + "fmt" + "log" + "io" + "io/fs" + "path" +) + +type DiskFile struct { + fs *FS // file system to which this file belongs + file fs.File // underlying file + path string // absolute path from the root of the fs. +} + +func (f *DiskFile) pathName() string { return f.path } +func (f *DiskFile) t() uint16 { return 0 } +func (f *DiskFile) dev() uint32 { return 0 } +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 (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 := f.qid() + uid := f.uid() + gid := f.gid() + muid := f.muid() + + fi := &FileInfo{ + info: fsfi, + stat: &stat{ + qid: &qid, + name: fsfi.Name(), + mode: fsModeTo9Mode(fsfi.Mode()), + aTime: uint32(fsfi.ModTime().Unix()), + mTime: uint32(fsfi.ModTime().Unix()), + length: fsfi.Size(), + uid: uid, // TODO: uid, gid, muid + gid: gid, + muid: muid, + }, + } + return fi, nil +} + +func (f *DiskFile) Close() error { + return f.file.Close() +} + +func (f *DiskFile) Read(b []byte) (int, error) { + return f.file.Read(b) +} + +func (f *DiskFile) ReadAt(p []byte, off int64) (int, error) { + if f, ok := f.file.(io.ReaderAt); ok { + return f.ReadAt(p, off) + } + file := f.file + + buf := make([]byte, 8*1024) // TODO: set appropreate size + var n int64 + for n+int64(len(buf)) < off { + m, err := file.Read(buf) + if err != nil { + return 0, err + } + n += int64(m) + } + m, err := file.Read(buf[:off-n]) + if err != nil { + return 0, err + } + n += int64(m) + if n != off { + panic("wrong offset") + } + return file.Read(p) +} + +func (f *DiskFile) ReadDir(n int) ([]*DirEntry, error) { + fi, err := f.file.Stat() + if err != nil { + return nil, fmt.Errorf("stat: %v", err) + } + dir, ok := f.file.(fs.ReadDirFile) + if !ok || !fi.IsDir() { + return nil, fmt.Errorf("not a directory") + } + fsde, err := dir.ReadDir(n) + if err != nil { + return nil, err + } + de := make([]*DirEntry, len(fsde)) + for i := 0; i < len(de); i++ { + fpath := path.Join(f.path, fsde[i].Name()) + file, err := f.fs.Open(fpath) + 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) + } + de[i] = &DirEntry{ + dirEnt: fsde[i], + info: info.(*FileInfo), + file: file, + } + } + return de, nil +} diff --git a/file.go b/file.go @@ -3,10 +3,7 @@ package lib9p import ( "fmt" "io/fs" - "io" - "log" "os" - "path" "time" ) @@ -152,30 +149,6 @@ func (fi *FileInfo) IsDir() bool { return fi.info.IsDir() } func (fi *FileInfo) Sys() any { return fi.stat } func (fi *FileInfo) Qid() *Qid { return fi.Sys().(*stat).qid } -type DiskFile struct { - fs *FS // file system to which this file belongs - file fs.File // underlying file - 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 - - // 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 - */ -} type File interface { fs.File @@ -212,33 +185,6 @@ func sameFile(fi0, fi1 fs.FileInfo) bool { return os.SameFile(fi0, fi1) } -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) @@ -253,101 +199,6 @@ func openFile(fsys *FS, fpath string) (*DiskFile, error) { return f, nil } -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 := f.qid() - uid := f.uid() - gid := f.gid() - muid := f.muid() - - fi := &FileInfo{ - info: fsfi, - stat: &stat{ - qid: &qid, - name: fsfi.Name(), - mode: fsModeTo9Mode(fsfi.Mode()), - aTime: uint32(fsfi.ModTime().Unix()), - mTime: uint32(fsfi.ModTime().Unix()), - length: fsfi.Size(), - uid: uid, // TODO: uid, gid, muid - gid: gid, - muid: muid, - }, - } - return fi, nil -} - -func (f *DiskFile) Close() error { - return f.file.Close() -} - -func (f *DiskFile) Read(b []byte) (int, error) { - return f.file.Read(b) -} - -func (f *DiskFile) ReadAt(p []byte, off int64) (int, error) { - if f, ok := f.file.(io.ReaderAt); ok { - return f.ReadAt(p, off) - } - file := f.file - - buf := make([]byte, 8*1024) // TODO: set appropreate size - var n int64 - for n+int64(len(buf)) < off { - m, err := file.Read(buf) - if err != nil { - return 0, err - } - n += int64(m) - } - m, err := file.Read(buf[:off-n]) - if err != nil { - return 0, err - } - n += int64(m) - if n != off { - panic("wrong offset") - } - return file.Read(p) -} - -func (f *DiskFile) ReadDir(n int) ([]*DirEntry, error) { - fi, err := f.file.Stat() - if err != nil { - return nil, fmt.Errorf("stat: %v", err) - } - dir, ok := f.file.(fs.ReadDirFile) - if !ok || !fi.IsDir() { - return nil, fmt.Errorf("not a directory") - } - fsde, err := dir.ReadDir(n) - if err != nil { - return nil, err - } - de := make([]*DirEntry, len(fsde)) - for i := 0; i < len(de); i++ { - fpath := path.Join(f.path, fsde[i].Name()) - file, err := f.fs.Open(fpath) - 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) - } - de[i] = &DirEntry{ - dirEnt: fsde[i], - info: info.(*FileInfo), - file: file, - } - } - return de, nil -} - type DirEntry struct { dirEnt fs.DirEntry // underlying fs.DirEntry info *FileInfo diff --git a/fs.go b/fs.go @@ -11,7 +11,7 @@ type FS struct { qidPool *QidPool } -func (fsys *FS) Open(name string) (*DiskFile, error) { +func (fsys *FS) Open(name string) (File, 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 @@ -47,8 +47,8 @@ func allocQidPool() *QidPool { } } -func (pool *QidPool) lookup(f *DiskFile) (Qid, bool) { - id, err := f.id() +func (pool *QidPool) lookup(f File) (Qid, bool) { + id, err := f.(*DiskFile).id() if err != nil { return Qid{}, false } @@ -56,12 +56,12 @@ func (pool *QidPool) lookup(f *DiskFile) (Qid, bool) { return qid, ok } -func (pool *QidPool) alloc(f *DiskFile) (Qid, error) { - id, err := f.id() +func (pool *QidPool) alloc(f File) (Qid, error) { + id, err := f.(*DiskFile).id() if err != nil { return Qid{}, fmt.Errorf("get id: %v", err) } - fi, err := f.file.Stat() + fi, err := f.(*DiskFile).file.Stat() if err != nil { return Qid{}, fmt.Errorf("stat %v: %v", f, err) } @@ -74,8 +74,8 @@ func (pool *QidPool) alloc(f *DiskFile) (Qid, error) { return qid, nil } -func (pool *QidPool) delete(f *DiskFile) { - id, err := f.id() +func (pool *QidPool) delete(f File) { + id, err := f.(*DiskFile).id() if err != nil { return } diff --git a/server.go b/server.go @@ -217,10 +217,7 @@ func rWalk(r *Req, err error) { } func sOpen(s *Server, r *Req) { - ifcall, ok := r.ifcall.(*TOpen) - if !ok { - panic("not TOpen") - } + ifcall := r.ifcall.(*TOpen) fidNum := ifcall.Fid() fidStruct, ok := s.fPool.lookup(fidNum) if !ok { @@ -265,12 +262,10 @@ func sOpen(s *Server, r *Req) { respond(r, fmt.Errorf("internal error")) return } - /* - if !ok { - respond(r, fmt.Errorf("permission denied")) - return - } - */ + if !ok { + respond(r, fmt.Errorf("permission denied")) + return + } if ifcall.Mode()&ORCLOSE != 0 { panic("ORCLOSE not implemented") @@ -298,13 +293,12 @@ func sRead(s *Server, r *Req) { respond(r, fmt.Errorf("not open")) return } - /* - if fid.OMode|OREAD == 0 || fid.OMode|ORDWR == 0 { - log.Printf("permission: %o\n", fid.OMode) - respond(r, fmt.Errorf("permission denied")) - return - } - */ + + if fid.OMode != OREAD && fid.OMode != ORDWR && fid.OMode != OEXEC { + respond(r, fmt.Errorf("permission denied")) + return + } + data := make([]byte, ifcall.Count()) var n int var err error @@ -483,7 +477,7 @@ func respond(r *Req, err error) { // free tag. if r.pool == nil && err != EDupTag { - panic("ReqPool is nil buf err is not EDupTag") + panic("ReqPool is nil but err is not EDupTag") } if r.pool != nil { if err := r.pool.deleteReq(r.ifcall.Tag()); err != nil {