commit 0c7b1e586f357f47d72d06d12437549f6a675706
parent 7e515ad7cc20e51a137378d22abae7164d23e286
Author: Matsuda Kenji <info@mtkn.jp>
Date: Tue, 19 Dec 2023 14:46:05 +0900
add test for chgrp
Diffstat:
4 files changed, 75 insertions(+), 29 deletions(-)
diff --git a/diskfs/file.go b/diskfs/file.go
@@ -84,7 +84,7 @@ func (f *File) ReadDir(n int) ([]fs.DirEntry, error) {
id := idFromInfo(f.path, fi)
stat, err := fiStat(f.fs.qidPool, id, fi)
if err != nil {
- return nil, fmt.Errorf("fiStat: %v")
+ return nil, fmt.Errorf("fiStat: %v", err)
}
de[i] = &lib9p.DirEntry{Stat: *stat}
diff --git a/diskfs/stat_unix.go b/diskfs/stat_unix.go
@@ -141,7 +141,7 @@ func (f *File) wstat(s *lib9p.Stat) error {
if err := os.Chown(filepath.Join(f.fs.rootPath, f.path), u, g); err != nil {
return fmt.Errorf("chown: %v", err)
}
- st, err := fs.Stat(lib9p.ExportFS{f.fs}, filepath.Join(f.fs.rootPath, f.path))
+ st, err := os.Stat(filepath.Join(f.fs.rootPath, f.path))
if err != nil {
return fmt.Errorf("stat: %v", err)
}
@@ -159,26 +159,3 @@ func (f *File) wstat(s *lib9p.Stat) error {
}
return nil
}
-
-func chown(ospath string, uid, gid string) error {
- usr, err := user.Lookup(uid)
- if err != nil {
- return fmt.Errorf("lookup user: %v", err)
- }
- u, err := strconv.Atoi(usr.Uid)
- if err != nil {
- return fmt.Errorf("convert uid: %v", err)
- }
- group, err := user.LookupGroup(gid)
- if err != nil {
- return fmt.Errorf("lookupgroup: %v", err)
- }
- g, err := strconv.Atoi(group.Gid)
- if err != nil {
- return fmt.Errorf("convert gid: %v", err)
- }
- if err := os.Chown(ospath, u, g); err != nil {
- return fmt.Errorf("set owner and group: %v", err)
- }
- return nil
-}
-\ No newline at end of file
diff --git a/diskfs/stat_unix_test.go b/diskfs/stat_unix_test.go
@@ -1,3 +1,4 @@
+//go:build unix
package diskfs
import (
@@ -38,4 +39,64 @@ func BenchmarkGID(b *testing.B) {
b.Fatalf("stat: %v", err)
}
}
+}
+
+func TestChgrp(t *testing.T) {
+ cr, sw := io.Pipe()
+ defer cr.Close()
+ defer sw.Close()
+ sr, cw := io.Pipe()
+ defer sr.Close()
+ defer cw.Close()
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+ disk, err := Open(testdir)
+ if err != nil {
+ t.Fatalf("open dir: %v", err)
+ }
+ s := lib9p.NewServer(disk, 8*1024, sr, sw)
+ go s.Serve(ctx)
+ c := client.NewClient(8*1024, "kenji", cr, cw)
+ defer c.Stop()
+ _, err = c.Attach(ctx, ^uint16(0), 0, lib9p.NOFID, "kenji", "")
+ if err != nil {
+ t.Fatalf("attach: %v", err)
+ }
+ wname := []string{"a"}
+ wqid, err := c.Walk(ctx, 0, 0, 1, wname)
+ if len(wqid) != len(wname) || err != nil {
+ t.Fatalf("file not found: %v", err)
+ }
+ st, err := c.Stat(ctx, 0, 1)
+ if err != nil {
+ t.Fatalf("stat: %v", err)
+ }
+ oldGid := st.Gid
+ t.Logf("old stat: %v", st)
+ st.Gid = "wheel"
+ err = c.Wstat(ctx, 0, 1, st)
+ if err != nil {
+ t.Fatalf("wstat: %v", err)
+ }
+ st, err = c.Stat(ctx, 0, 1)
+ if err != nil {
+ t.Fatalf("stat: %v", err)
+ }
+ t.Logf("new stat: %v", st)
+ if st.Gid != "wheel" {
+ t.Fatal("gid not changed to wheel.")
+ }
+ st.Gid = oldGid
+ err = c.Wstat(ctx, 0, 1, st)
+ if err != nil {
+ t.Fatalf("wstat: %v", err)
+ }
+ st, err = c.Stat(ctx, 0, 1)
+ if err != nil {
+ t.Fatalf("stat: %v", err)
+ }
+ t.Logf("restored stat: %v", st)
+ if st.Gid != oldGid {
+ t.Fatalf("gid not restored to %v.", oldGid)
+ }
}
\ No newline at end of file
diff --git a/server.go b/server.go
@@ -880,10 +880,19 @@ func sWStat(ctx context.Context, s *Server, r *Req) {
}
newStat.Mtime = wstat.Mtime
}
+ // TODO: check group membership
+ // now group member == group leader == gid
if wstat.Gid != "" && wstat.Gid != newStat.Gid {
- // TODO implement
- Respond(ctx, r, fmt.Errorf("not implemented"))
- return
+ // by the owner if also a member of the new group;
+ // or by the group leader of the file's current group if
+ // also the leader of the new group.
+ if r.Fid.Uid == newStat.Uid && r.Fid.Uid == wstat.Gid ||
+ r.Fid.Uid == newStat.Gid && r.Fid.Uid == wstat.Gid {
+ newStat.Gid = wstat.Gid
+ } else {
+ Respond(ctx, r, ErrPerm)
+ return
+ }
}
err = wsfile.WStat(newStat)
if err != nil {