lib9p

Go 9P library.
Log | Files | Refs

commit 2e4e8eddbd83461ead985795e3de594b4d74b40b
parent c6af3f65b27200506b27c21cbabb21c6a437a729
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue, 12 Sep 2023 09:11:15 +0900

partly implement

Diffstat:
Mdiskfs/diskfs.go | 2+-
Mdiskfs/file.go | 69++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mserver.go | 4++++
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: