commit 497a942661c9113976dd5db8df9d0e31aa3fb96a
parent 6589901ae37b7c51764260dc48e1eec9e34b0b67
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sat, 26 Aug 2023 10:00:44 +0900
split functions
Diffstat:
| D | disk.go | | | 2 | -- |
| A | disk_unix.go | | | 138 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | file.go | | | 149 | ------------------------------------------------------------------------------- |
| M | fs.go | | | 2 | +- |
| M | qid_unix.go | | | 14 | +++++++------- |
| M | server.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 {