unix: do not return non-nil error for 0 errno in FcntlInt
Fixes golang/go#26078
Change-Id: Ie5a8c7028a755bc7a8d56abc4736a5f61ef91ce5
Reviewed-on: https://go-review.googlesource.com/121175
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/unix/fcntl.go b/unix/fcntl.go
index 0c58c7e..9379ba9 100644
--- a/unix/fcntl.go
+++ b/unix/fcntl.go
@@ -14,7 +14,11 @@
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
- valptr, _, err := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(arg))
+ valptr, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(arg))
+ var err error
+ if errno != 0 {
+ err = errno
+ }
return int(valptr), err
}
diff --git a/unix/syscall_solaris.go b/unix/syscall_solaris.go
index 4d7efbc..820ef77 100644
--- a/unix/syscall_solaris.go
+++ b/unix/syscall_solaris.go
@@ -314,7 +314,11 @@
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
- valptr, _, err := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
+ valptr, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
+ var err error
+ if errno != 0 {
+ err = errno
+ }
return int(valptr), err
}
diff --git a/unix/syscall_unix_test.go b/unix/syscall_unix_test.go
index ad09716..d694990 100644
--- a/unix/syscall_unix_test.go
+++ b/unix/syscall_unix_test.go
@@ -98,6 +98,24 @@
}
}
+func TestFcntlInt(t *testing.T) {
+ t.Parallel()
+ file, err := ioutil.TempFile("", "TestFnctlInt")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.Remove(file.Name())
+ defer file.Close()
+ f := file.Fd()
+ flags, err := unix.FcntlInt(f, unix.F_GETFD, 0)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if flags&unix.FD_CLOEXEC == 0 {
+ t.Errorf("flags %#x do not include FD_CLOEXEC", flags)
+ }
+}
+
// TestFcntlFlock tests whether the file locking structure matches
// the calling convention of each kernel.
func TestFcntlFlock(t *testing.T) {