Просмотр исходного кода

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>
Ian Lance Taylor 7 лет назад
Родитель
Сommit
7138fd3d9d
3 измененных файлов с 28 добавлено и 2 удалено
  1. 5 1
      unix/fcntl.go
  2. 5 1
      unix/syscall_solaris.go
  3. 18 0
      unix/syscall_unix_test.go

+ 5 - 1
unix/fcntl.go

@@ -14,7 +14,11 @@ var fcntl64Syscall uintptr = SYS_FCNTL
 
 // 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
 }
 

+ 5 - 1
unix/syscall_solaris.go

@@ -314,7 +314,11 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
 
 // 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
 }
 

+ 18 - 0
unix/syscall_unix_test.go

@@ -98,6 +98,24 @@ func TestErrnoSignalName(t *testing.T) {
 	}
 }
 
+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) {