Russ Cox | 8dce57e | 2011-11-30 12:04:16 -0500 | [diff] [blame] | 1 | // Copyright 2009 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
Aram Hăvărneanu | 6d0d08b | 2014-01-10 02:49:37 +1100 | [diff] [blame] | 5 | // +build darwin dragonfly freebsd linux netbsd openbsd solaris |
Russ Cox | 8dce57e | 2011-11-30 12:04:16 -0500 | [diff] [blame] | 6 | |
| 7 | package os_test |
| 8 | |
| 9 | import ( |
| 10 | . "os" |
Mikio Hara | 92c8df4 | 2012-01-14 06:40:55 +0900 | [diff] [blame] | 11 | "runtime" |
Russ Cox | 8dce57e | 2011-11-30 12:04:16 -0500 | [diff] [blame] | 12 | "syscall" |
| 13 | "testing" |
| 14 | ) |
| 15 | |
David du Colombier | 187cccb | 2015-02-02 17:40:47 +0100 | [diff] [blame] | 16 | func init() { |
| 17 | isReadonlyError = func(err error) bool { return err == syscall.EROFS } |
| 18 | } |
| 19 | |
Russ Cox | 8dce57e | 2011-11-30 12:04:16 -0500 | [diff] [blame] | 20 | func checkUidGid(t *testing.T, path string, uid, gid int) { |
| 21 | dir, err := Stat(path) |
| 22 | if err != nil { |
| 23 | t.Fatalf("Stat %q (looking for uid/gid %d/%d): %s", path, uid, gid, err) |
| 24 | } |
Gustavo Niemeyer | 20f4385 | 2012-02-03 00:16:18 -0200 | [diff] [blame] | 25 | sys := dir.Sys().(*syscall.Stat_t) |
Russ Cox | 8dce57e | 2011-11-30 12:04:16 -0500 | [diff] [blame] | 26 | if int(sys.Uid) != uid { |
| 27 | t.Errorf("Stat %q: uid %d want %d", path, sys.Uid, uid) |
| 28 | } |
| 29 | if int(sys.Gid) != gid { |
| 30 | t.Errorf("Stat %q: gid %d want %d", path, sys.Gid, gid) |
| 31 | } |
| 32 | } |
| 33 | |
| 34 | func TestChown(t *testing.T) { |
Pieter Droogendijk | bdbd541 | 2013-08-08 10:44:01 -0700 | [diff] [blame] | 35 | // Chown is not supported under windows os Plan 9. |
Russ Cox | 8dce57e | 2011-11-30 12:04:16 -0500 | [diff] [blame] | 36 | // Plan9 provides a native ChownPlan9 version instead. |
Mikio Hara | 92c8df4 | 2012-01-14 06:40:55 +0900 | [diff] [blame] | 37 | if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { |
Russ Cox | 8dce57e | 2011-11-30 12:04:16 -0500 | [diff] [blame] | 38 | return |
| 39 | } |
| 40 | // Use TempDir() to make sure we're on a local file system, |
| 41 | // so that the group ids returned by Getgroups will be allowed |
| 42 | // on the file. On NFS, the Getgroups groups are |
| 43 | // basically useless. |
| 44 | f := newFile("TestChown", t) |
| 45 | defer Remove(f.Name()) |
| 46 | defer f.Close() |
| 47 | dir, err := f.Stat() |
| 48 | if err != nil { |
| 49 | t.Fatalf("stat %s: %s", f.Name(), err) |
| 50 | } |
| 51 | |
| 52 | // Can't change uid unless root, but can try |
| 53 | // changing the group id. First try our current group. |
| 54 | gid := Getgid() |
| 55 | t.Log("gid:", gid) |
| 56 | if err = Chown(f.Name(), -1, gid); err != nil { |
| 57 | t.Fatalf("chown %s -1 %d: %s", f.Name(), gid, err) |
| 58 | } |
Gustavo Niemeyer | 20f4385 | 2012-02-03 00:16:18 -0200 | [diff] [blame] | 59 | sys := dir.Sys().(*syscall.Stat_t) |
Russ Cox | 8dce57e | 2011-11-30 12:04:16 -0500 | [diff] [blame] | 60 | checkUidGid(t, f.Name(), int(sys.Uid), gid) |
| 61 | |
| 62 | // Then try all the auxiliary groups. |
| 63 | groups, err := Getgroups() |
| 64 | if err != nil { |
| 65 | t.Fatalf("getgroups: %s", err) |
| 66 | } |
| 67 | t.Log("groups: ", groups) |
| 68 | for _, g := range groups { |
| 69 | if err = Chown(f.Name(), -1, g); err != nil { |
| 70 | t.Fatalf("chown %s -1 %d: %s", f.Name(), g, err) |
| 71 | } |
| 72 | checkUidGid(t, f.Name(), int(sys.Uid), g) |
| 73 | |
| 74 | // change back to gid to test fd.Chown |
| 75 | if err = f.Chown(-1, gid); err != nil { |
| 76 | t.Fatalf("fchown %s -1 %d: %s", f.Name(), gid, err) |
| 77 | } |
| 78 | checkUidGid(t, f.Name(), int(sys.Uid), gid) |
| 79 | } |
| 80 | } |