From 7937466022627d90ffde9ddfb2499023c060c8a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Tue, 4 Dec 2018 09:03:32 +0100 Subject: [PATCH] syscall, cmd/go/internal/lockedfile: remove Flock syscall for aix/ppc64 AIX doesn't provide flock() syscall, it was previously emulated by fcntl calls. However, there are some differences between a flock() syscall and a flock() using fcntl. Therefore, it's safer to remove it and just provide FcntlFlock. Thus, lockedfile implementation must be moved to use FcntlFlock on aix/ppc64. Updates #29065. Fixes #29084. Change-Id: Ic48fd9f315f24c2acdf09b91d917da131a1f2dd5 Reviewed-on: https://go-review.googlesource.com/c/152397 Reviewed-by: Tobias Klauser Reviewed-by: Bryan C. Mills --- ...{filelock_solaris.go => filelock_fcntl.go} | 6 ++-- .../internal/filelock/filelock_other.go | 2 +- .../internal/filelock/filelock_test.go | 4 +-- src/syscall/flock_aix.go | 31 +++---------------- 4 files changed, 11 insertions(+), 32 deletions(-) rename src/cmd/go/internal/lockedfile/internal/filelock/{filelock_solaris.go => filelock_fcntl.go} (97%) diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_solaris.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go similarity index 97% rename from src/cmd/go/internal/lockedfile/internal/filelock/filelock_solaris.go rename to src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go index b03d5f893e9..2831975c0c6 100644 --- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_solaris.go +++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build aix solaris + // This code implements the filelock API using POSIX 'fcntl' locks, which attach // to an (inode, process) pair rather than a file descriptor. To avoid unlocking // files prematurely when the same file is opened through different descriptors, @@ -13,8 +15,8 @@ // // TODO(bcmills): If we add a build tag for Illumos (see golang.org/issue/20603) // then Illumos should use F_OFD_SETLK, and the resulting code would be as -// simple as filelock_unix.go. We will still need the code in this file as long -// as Oracle Solaris provides only F_SETLK. +// simple as filelock_unix.go. We will still need the code in this file for AIX +// or as long as Oracle Solaris provides only F_SETLK. package filelock diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go index 7d60160f909..107611e1ce8 100644 --- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go +++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_other.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 !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!plan9,!solaris,!windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!plan9,!solaris,!windows package filelock diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go index 0ccee07ceeb..aa67093a48a 100644 --- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go +++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go @@ -159,7 +159,7 @@ func TestRLockExcludesOnlyLock(t *testing.T) { f2 := mustOpen(t, f.Name()) defer f2.Close() - if runtime.GOOS == "solaris" { + if runtime.GOOS == "solaris" || runtime.GOOS == "aix" { // When using POSIX locks (as on Solaris), we can't safely read-lock the // same inode through two different descriptors at the same time: when the // first descriptor is closed, the second descriptor would still be open but @@ -176,7 +176,7 @@ func TestRLockExcludesOnlyLock(t *testing.T) { lockOther := mustBlock(t, "Lock", other) unlock(t, f2) - if runtime.GOOS != "solaris" { + if runtime.GOOS != "solaris" && runtime.GOOS != "aix" { unlock(t, f) } lockOther(t) diff --git a/src/syscall/flock_aix.go b/src/syscall/flock_aix.go index 9745236dcb8..c9eab43b6bc 100644 --- a/src/syscall/flock_aix.go +++ b/src/syscall/flock_aix.go @@ -6,36 +6,13 @@ package syscall import "unsafe" -// On AIX, there is no flock() system call, we emulate it. -// Moreover, we can't call the default fcntl syscall because the arguments -// must be integer and it's not possible to transform a pointer (lk) -// to a int value. -// It's easier to call syscall6 than to transform fcntl for every GOOS. -func fcntlFlock(fd, cmd int, lk *Flock_t) (err error) { +// On AIX, there is no flock() system call. + +// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. +func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) (err error) { _, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_fcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0) if e1 != 0 { err = errnoErr(e1) } return } - -func Flock(fd int, op int) (err error) { - lk := &Flock_t{} - if (op & LOCK_UN) != 0 { - lk.Type = F_UNLCK - } else if (op & LOCK_EX) != 0 { - lk.Type = F_WRLCK - } else if (op & LOCK_SH) != 0 { - lk.Type = F_RDLCK - } else { - return nil - } - if (op & LOCK_NB) != 0 { - err = fcntlFlock(fd, F_SETLK, lk) - if err != nil && (err == EAGAIN || err == EACCES) { - return EWOULDBLOCK - } - return err - } - return fcntlFlock(fd, F_SETLKW, lk) -}