Commit 79374660 authored by Clément Chigot's avatar Clément Chigot Committed by Tobias Klauser

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/152397Reviewed-by: 's avatarTobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: 's avatarBryan C. Mills <bcmills@google.com>
parent ffac3d5a
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build aix solaris
// This code implements the filelock API using POSIX 'fcntl' locks, which attach // 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 // to an (inode, process) pair rather than a file descriptor. To avoid unlocking
// files prematurely when the same file is opened through different descriptors, // files prematurely when the same file is opened through different descriptors,
...@@ -13,8 +15,8 @@ ...@@ -13,8 +15,8 @@
// //
// TODO(bcmills): If we add a build tag for Illumos (see golang.org/issue/20603) // 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 // 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 // simple as filelock_unix.go. We will still need the code in this file for AIX
// as Oracle Solaris provides only F_SETLK. // or as long as Oracle Solaris provides only F_SETLK.
package filelock package filelock
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // 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 package filelock
......
...@@ -159,7 +159,7 @@ func TestRLockExcludesOnlyLock(t *testing.T) { ...@@ -159,7 +159,7 @@ func TestRLockExcludesOnlyLock(t *testing.T) {
f2 := mustOpen(t, f.Name()) f2 := mustOpen(t, f.Name())
defer f2.Close() 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 // 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 // same inode through two different descriptors at the same time: when the
// first descriptor is closed, the second descriptor would still be open but // first descriptor is closed, the second descriptor would still be open but
...@@ -176,7 +176,7 @@ func TestRLockExcludesOnlyLock(t *testing.T) { ...@@ -176,7 +176,7 @@ func TestRLockExcludesOnlyLock(t *testing.T) {
lockOther := mustBlock(t, "Lock", other) lockOther := mustBlock(t, "Lock", other)
unlock(t, f2) unlock(t, f2)
if runtime.GOOS != "solaris" { if runtime.GOOS != "solaris" && runtime.GOOS != "aix" {
unlock(t, f) unlock(t, f)
} }
lockOther(t) lockOther(t)
......
...@@ -6,36 +6,13 @@ package syscall ...@@ -6,36 +6,13 @@ package syscall
import "unsafe" import "unsafe"
// On AIX, there is no flock() system call, we emulate it. // On AIX, there is no flock() system call.
// 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) // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
// to a int value. func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) (err error) {
// It's easier to call syscall6 than to transform fcntl for every GOOS.
func fcntlFlock(fd, 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) _, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_fcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
if e1 != 0 { if e1 != 0 {
err = errnoErr(e1) err = errnoErr(e1)
} }
return 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)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment