From 372efbbf3170ccf260186118cd3acf7f617055ae Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 20 Dec 2019 13:05:24 -0800 Subject: [PATCH] internal/syscall/unix: use fcntl64 on 32-bit GNU/Linux systems Patch up runtime testing to use the libc fcntl function on Darwin, which is what we should be doing anyhow. This is similar to how we handle fcntl on AIX and Solaris. Fixes #36211 Change-Id: I47ad87e11df043ce21496a0d59523dad28960f76 Reviewed-on: https://go-review.googlesource.com/c/go/+/212299 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Tobias Klauser --- src/internal/syscall/unix/fcntl_linux_32bit.go | 16 ++++++++++++++++ src/internal/syscall/unix/nonblocking.go | 6 +++++- src/runtime/export_darwin_test.go | 13 +++++++++++++ src/runtime/nbpipe_fcntl_libc_test.go | 2 +- src/runtime/nbpipe_fcntl_unix_test.go | 9 ++++++--- src/syscall/flock_linux_32bit.go | 7 +++++-- 6 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 src/internal/syscall/unix/fcntl_linux_32bit.go create mode 100644 src/runtime/export_darwin_test.go diff --git a/src/internal/syscall/unix/fcntl_linux_32bit.go b/src/internal/syscall/unix/fcntl_linux_32bit.go new file mode 100644 index 00000000000..6c75afc2abe --- /dev/null +++ b/src/internal/syscall/unix/fcntl_linux_32bit.go @@ -0,0 +1,16 @@ +// Copyright 2019 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. + +// On 32-bit Linux systems, use SYS_FCNTL64. +// If you change the build tags here, see syscall/flock_linux_32bit.go. + +// +build linux,386 linux,arm linux,mips linux,mipsle + +package unix + +import "syscall" + +func init() { + FcntlSyscall = syscall.SYS_FCNTL64 +} diff --git a/src/internal/syscall/unix/nonblocking.go b/src/internal/syscall/unix/nonblocking.go index bcc350b56e1..545445204f5 100644 --- a/src/internal/syscall/unix/nonblocking.go +++ b/src/internal/syscall/unix/nonblocking.go @@ -8,8 +8,12 @@ package unix import "syscall" +// FcntlSyscall is the number for the fcntl system call. This is +// usually SYS_FCNTL, but can be overridden to SYS_FCNTL64. +var FcntlSyscall uintptr = syscall.SYS_FCNTL + func IsNonblock(fd int) (nonblocking bool, err error) { - flag, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), uintptr(syscall.F_GETFL), 0) + flag, _, e1 := syscall.Syscall(FcntlSyscall, uintptr(fd), uintptr(syscall.F_GETFL), 0) if e1 != 0 { return false, e1 } diff --git a/src/runtime/export_darwin_test.go b/src/runtime/export_darwin_test.go new file mode 100644 index 00000000000..e9b6eb36da5 --- /dev/null +++ b/src/runtime/export_darwin_test.go @@ -0,0 +1,13 @@ +// Copyright 2019 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. + +package runtime + +func Fcntl(fd, cmd, arg uintptr) (uintptr, uintptr) { + r := fcntl(int32(fd), int32(cmd), int32(arg)) + if r < 0 { + return ^uintptr(0), uintptr(-r) + } + return uintptr(r), 0 +} diff --git a/src/runtime/nbpipe_fcntl_libc_test.go b/src/runtime/nbpipe_fcntl_libc_test.go index 70f4b8348ba..b38c58399bc 100644 --- a/src/runtime/nbpipe_fcntl_libc_test.go +++ b/src/runtime/nbpipe_fcntl_libc_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix solaris +// +build aix darwin solaris package runtime_test diff --git a/src/runtime/nbpipe_fcntl_unix_test.go b/src/runtime/nbpipe_fcntl_unix_test.go index 06b3275f062..75acdb62ddd 100644 --- a/src/runtime/nbpipe_fcntl_unix_test.go +++ b/src/runtime/nbpipe_fcntl_unix_test.go @@ -2,13 +2,16 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd linux netbsd openbsd +// +build dragonfly freebsd linux netbsd openbsd package runtime_test -import "syscall" +import ( + "internal/syscall/unix" + "syscall" +) func fcntl(fd uintptr, cmd int, arg uintptr) (uintptr, syscall.Errno) { - res, _, err := syscall.Syscall(syscall.SYS_FCNTL, fd, uintptr(cmd), arg) + res, _, err := syscall.Syscall(unix.FcntlSyscall, fd, uintptr(cmd), arg) return res, err } diff --git a/src/syscall/flock_linux_32bit.go b/src/syscall/flock_linux_32bit.go index e1548995b21..e11aed6ed1a 100644 --- a/src/syscall/flock_linux_32bit.go +++ b/src/syscall/flock_linux_32bit.go @@ -1,9 +1,12 @@ -// +build linux,386 linux,arm linux,mips linux,mipsle - // 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. +// If you change the build tags here, see +// internal/syscall/unix/fcntl_linux_32bit.go. + +// +build linux,386 linux,arm linux,mips linux,mipsle + package syscall func init() {