aboutsummaryrefslogtreecommitdiff
path: root/src/syscall/syscall_linux_test.go
diff options
context:
space:
mode:
authorTobias Klauser <tklauser@distanz.ch>2018-06-13 15:54:42 +0200
committerTobias Klauser <tobias.klauser@gmail.com>2018-06-13 20:32:08 +0000
commitfb4fb0430b8d77b5487f51fd780bba25476e816c (patch)
tree8c8c1812e404a0d903278af37e750a4826f5d9a5 /src/syscall/syscall_linux_test.go
parent4a778cdf3375d418062b3c3e9f6891cc9162e3d0 (diff)
downloadgo-fb4fb0430b8d77b5487f51fd780bba25476e816c.tar.xz
syscall: check Fchmodat flags parameter on Linux
As mentioned in #25845, port CL 46474 from golang.org/x/sys/unix to the syscall package. Currently Linux' fchmodat(2) syscall implementation doesn't support the flags parameter (though it might in future versions [1]). Fchmodat in the syscall package takes the parameter and (wrongly) passes it on to the syscall which will ignore it. According to the POSIX.1-2008 manual page [2], AT_SYMLINK_NOFOLLOW is the only valid value for the flags parameter and EOPNOTSUPP should be returned in case changing the mode of a symbolic link is not supported by the underlying system. EINVAL should be returned for any other value of the flags parameter. [1] https://patchwork.kernel.org/patch/9596301/ [2] http://pubs.opengroup.org/onlinepubs/9699919799/functions/chmod.html Updates #20130 Updates #25845 Change-Id: I1021dd0e6a4f4cb3557cb1c1b34dd618c378cda6 Reviewed-on: https://go-review.googlesource.com/118658 Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/syscall/syscall_linux_test.go')
-rw-r--r--src/syscall/syscall_linux_test.go63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/syscall/syscall_linux_test.go b/src/syscall/syscall_linux_test.go
index 932ccee491..4490fc24ca 100644
--- a/src/syscall/syscall_linux_test.go
+++ b/src/syscall/syscall_linux_test.go
@@ -21,6 +21,69 @@ import (
"time"
)
+// chtmpdir changes the working directory to a new temporary directory and
+// provides a cleanup function. Used when PWD is read-only.
+func chtmpdir(t *testing.T) func() {
+ oldwd, err := os.Getwd()
+ if err != nil {
+ t.Fatalf("chtmpdir: %v", err)
+ }
+ d, err := ioutil.TempDir("", "test")
+ if err != nil {
+ t.Fatalf("chtmpdir: %v", err)
+ }
+ if err := os.Chdir(d); err != nil {
+ t.Fatalf("chtmpdir: %v", err)
+ }
+ return func() {
+ if err := os.Chdir(oldwd); err != nil {
+ t.Fatalf("chtmpdir: %v", err)
+ }
+ os.RemoveAll(d)
+ }
+}
+
+func touch(t *testing.T, name string) {
+ f, err := os.Create(name)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := f.Close(); err != nil {
+ t.Fatal(err)
+ }
+}
+
+const (
+ _AT_SYMLINK_NOFOLLOW = 0x100
+ _AT_FDCWD = -0x64
+)
+
+func TestFchmodat(t *testing.T) {
+ defer chtmpdir(t)()
+
+ touch(t, "file1")
+ os.Symlink("file1", "symlink1")
+
+ err := syscall.Fchmodat(_AT_FDCWD, "symlink1", 0444, 0)
+ if err != nil {
+ t.Fatalf("Fchmodat: unexpected error: %v", err)
+ }
+
+ fi, err := os.Stat("file1")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if fi.Mode() != 0444 {
+ t.Errorf("Fchmodat: failed to change mode: expected %v, got %v", 0444, fi.Mode())
+ }
+
+ err = syscall.Fchmodat(_AT_FDCWD, "symlink1", 0444, _AT_SYMLINK_NOFOLLOW)
+ if err != syscall.EOPNOTSUPP {
+ t.Fatalf("Fchmodat: unexpected error: %v, expected EOPNOTSUPP", err)
+ }
+}
+
func TestMain(m *testing.M) {
if os.Getenv("GO_DEATHSIG_PARENT") == "1" {
deathSignalParent()