commit 2e4e8eddbd83461ead985795e3de594b4d74b40b
parent c6af3f65b27200506b27c21cbabb21c6a437a729
Author: Matsuda Kenji <info@mtkn.jp>
Date: Tue, 12 Sep 2023 09:11:15 +0900
partly implement
Diffstat:
3 files changed, 71 insertions(+), 4 deletions(-)
diff --git a/diskfs/diskfs.go b/diskfs/diskfs.go
@@ -26,7 +26,7 @@ func Open(name string) *FS {
}
func (fsys *FS) Open(name string) (lib9p.File, error) {
- file, err := openFile(fsys, name)
+ file, err := openFile(fsys, name, lib9p.ORDWR)
if err != nil {
return nil, err
}
diff --git a/diskfs/file.go b/diskfs/file.go
@@ -19,7 +19,7 @@ type File struct {
diroff int // directory offset for ReadDir()
}
-func openFile(fsys *FS, fpath string) (*File, error) {
+func openFile(fsys *FS, fpath string, mode lib9p.OpenMode) (*File, error) {
fsfile, err := fsys.fs.Open(fpath)
if err != nil {
return nil, fmt.Errorf("fs open: %v", err)
@@ -33,7 +33,16 @@ func openFile(fsys *FS, fpath string) (*File, error) {
if fsfi.IsDir() {
file = fsfile.(*os.File)
} else {
- file, err = os.OpenFile(path.Join(fsys.rootPath, fpath), os.O_RDWR, 0)
+ var osmode int
+ switch mode {
+ case lib9p.OREAD:
+ osmode = os.O_RDONLY
+ case lib9p.OWRITE:
+ osmode = os.O_WRONLY
+ case lib9p.ORDWR:
+ osmode = os.O_RDWR
+ }
+ file, err = os.OpenFile(path.Join(fsys.rootPath, fpath), osmode, 0)
if err != nil {
return nil, fmt.Errorf("open fs: %v", err)
}
@@ -77,7 +86,6 @@ func (f *File) Fsys() lib9p.FS {
return f.fs
}
-
func (f *File) Stat() (*lib9p.FileInfo, error) {
fsfi, err := f.file.Stat()
if err != nil {
@@ -163,3 +171,58 @@ func (f *File) ReadDir(n int) ([]*lib9p.DirEntry, error) {
f.diroff += n
return childEntry[:n], nil
}
+
+func (f *File) Create(name string, uid string,
+ mode lib9p.OpenMode, perm lib9p.FileMode) (lib9p.File, error) {
+ dirinfo, err := f.Stat()
+ if err != nil {
+ return nil, fmt.Errorf("stat: %v", err)
+ }
+ if !dirinfo.IsDir() {
+ return nil, fmt.Errorf("not a directory")
+ }
+
+ ospath := path.Join(f.fs.rootPath, f.path, name)
+ fmt.Printf("pathname: %s\n", ospath)
+ osfile, err := os.Create(ospath)
+ if err != nil {
+ return nil, fmt.Errorf("create: %v", err)
+ }
+
+ usr, err := user.Lookup(uid)
+ if err != nil {
+ return nil, fmt.Errorf("lookup user: %v", err)
+ }
+ u, err := strconv.Atoi(usr.Uid)
+ if err != nil {
+ return nil, fmt.Errorf("convert uid: %v", err)
+ }
+ group, err := user.LookupGroup(dirinfo.Sys().(*lib9p.Stat).Gid)
+ if err != nil {
+ return nil, fmt.Errorf("lookupgroup: %v", err)
+ }
+ g, err := strconv.Atoi(group.Gid)
+ if err != nil {
+ return nil, fmt.Errorf("convert gid: %v", err)
+ }
+ if err := osfile.Chown(u, g); err != nil {
+ return nil, fmt.Errorf("set owner and group: %v", err)
+ }
+
+ if err := osfile.Chmod(lib9p.Mode9ToFSMode(perm)); err != nil {
+ return nil, fmt.Errorf("set file mode: %v", err)
+ }
+
+ fmt.Printf("file: %v\n", osfile)
+
+ if err := osfile.Close(); err != nil {
+ return nil, fmt.Errorf("close: %v", err)
+ }
+
+ file, err := openFile(f.fs, path.Join(f.path, name), mode)
+ if err != nil {
+ return nil, fmt.Errorf("open new file: %v", err)
+ }
+
+ return file, nil
+}
diff --git a/server.go b/server.go
@@ -641,6 +641,8 @@ func (s *Server) Serve() {
sWalk(s, r)
case *TOpen:
sOpen(s, r)
+ case *TCreate:
+ sCreate(s, r)
case *TRead:
sRead(s, r)
case *TWrite:
@@ -682,6 +684,8 @@ func respond(r *Req, err error) {
rWalk(r, err)
case *ROpen:
rOpen(r, err)
+ case *RCreate:
+ rCreate(r, err)
case *RRead:
rRead(r, err)
case *RWrite: