]> Cypherpunks repositories - gostls13.git/commitdiff
os: handle the sticky bit separately for *BSD and Solaris
authorKato Kazuyoshi <kato.kazuyoshi@gmail.com>
Tue, 16 Dec 2014 16:22:17 +0000 (08:22 -0800)
committerIan Lance Taylor <iant@golang.org>
Wed, 17 Dec 2014 16:07:28 +0000 (16:07 +0000)
open(2) and mkdir(2) won't set the sticky bit on *BSD and Solaris.
This behavior is mentioned on sticky(8).
see also: https://github.com/dotcloud/docker/pull/6587

Fixes #8383.

Change-Id: Ic4733700f9926b9fc2b6fd1f998acec34e518764
Reviewed-on: https://go-review.googlesource.com/1673
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/os/file.go
src/os/file_unix.go
src/os/sticky_bsd.go [new file with mode: 0644]
src/os/sticky_notbsd.go [new file with mode: 0644]

index e12428cbe129cf0615ea8cba2eb1c43256d9020f..79e8fc33882bd79b4a0fa572a05a1c591d1e8cff 100644 (file)
@@ -203,6 +203,12 @@ func (f *File) WriteString(s string) (ret int, err error) {
 // If there is an error, it will be of type *PathError.
 func Mkdir(name string, perm FileMode) error {
        e := syscall.Mkdir(name, syscallMode(perm))
+
+       // mkdir(2) itself won't handle the sticky bit on *BSD and Solaris
+       if !supportsCreateWithStickyBit && e == nil && perm&ModeSticky != 0 {
+               e = Chmod(name, perm)
+       }
+
        if e != nil {
                return &PathError{"mkdir", name, e}
        }
index ff4fc7d12e8b37fac34d0f123c8b137b085bfe55..fbe05c61a06c837ed57e3e4fa747b7153ceea340 100644 (file)
@@ -75,11 +75,23 @@ const DevNull = "/dev/null"
 // methods on the returned File can be used for I/O.
 // If there is an error, it will be of type *PathError.
 func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
+       chmod := false
+       if !supportsCreateWithStickyBit && flag&O_CREATE != 0 && perm&ModeSticky != 0 {
+               if _, err := Stat(name); IsNotExist(err) {
+                       chmod = true
+               }
+       }
+
        r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
        if e != nil {
                return nil, &PathError{"open", name, e}
        }
 
+       // open(2) itself won't handle the sticky bit on *BSD and Solaris
+       if chmod && e == nil {
+               e = Chmod(name, perm)
+       }
+
        // There's a race here with fork/exec, which we are
        // content to live with.  See ../syscall/exec_unix.go.
        if !supportsCloseOnExec {
diff --git a/src/os/sticky_bsd.go b/src/os/sticky_bsd.go
new file mode 100644 (file)
index 0000000..6b54c75
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd netbsd openbsd solaris
+
+package os
+
+// According to sticky(8), neither open(2) nor mkdir(2) will create
+// a file with the sticky bit set.
+const supportsCreateWithStickyBit = false
diff --git a/src/os/sticky_notbsd.go b/src/os/sticky_notbsd.go
new file mode 100644 (file)
index 0000000..834e79b
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !darwin
+// +build !dragonfly
+// +build !freebsd
+// +build !netbsd
+// +build !openbsd
+// +build !solaris
+
+package os
+
+const supportsCreateWithStickyBit = true