syscall, cmd/go/internal/lockedfile/internal/filelock: add and use Flock on illumos

Copy the syscall wrapper from golang.org/x/sys/unix CL 255377 to provide
Flock on illumos and switch cmd/go/internal/lockedfile/internal/filelock
to use it.

Fixes #35618

Change-Id: I876a2b782329a988fa85361fb1ea58eb6f329af1
Reviewed-on: https://go-review.googlesource.com/c/go/+/255258
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go
index c60a78e..dc7bbe2 100644
--- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go
+++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.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 solaris,!illumos
 
 // 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
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 faf7344..8301fb6 100644
--- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go
+++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go
@@ -161,7 +161,7 @@
 
 	doUnlockTF := false
 	switch runtime.GOOS {
-	case "aix", "illumos", "solaris":
+	case "aix", "solaris":
 		// 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
diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go
index 00c4262..78f2c51 100644
--- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go
+++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.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
+// +build darwin dragonfly freebsd illumos linux netbsd openbsd
 
 package filelock
 
diff --git a/src/syscall/syscall_illumos.go b/src/syscall/syscall_illumos.go
new file mode 100644
index 0000000..1484337
--- /dev/null
+++ b/src/syscall/syscall_illumos.go
@@ -0,0 +1,25 @@
+// Copyright 2020 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.
+
+// +build illumos
+
+// Illumos system calls not present on Solaris.
+
+package syscall
+
+import "unsafe"
+
+//go:cgo_import_dynamic libc_flock flock "libc.so"
+
+//go:linkname procFlock libc_flock
+
+var procFlock libcFunc
+
+func Flock(fd int, how int) error {
+	_, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procFlock)), 2, uintptr(fd), uintptr(how), 0, 0, 0, 0)
+	if errno != 0 {
+		return errno
+	}
+	return nil
+}
diff --git a/src/syscall/types_illumos_amd64.go b/src/syscall/types_illumos_amd64.go
new file mode 100644
index 0000000..abb282f
--- /dev/null
+++ b/src/syscall/types_illumos_amd64.go
@@ -0,0 +1,17 @@
+// Copyright 2020 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.
+
+// +build illumos
+
+// Illumos consts not present on Solaris. These are added manually rather than
+// auto-generated by mkerror.sh
+
+package syscall
+
+const (
+	LOCK_EX = 0x2
+	LOCK_NB = 0x4
+	LOCK_SH = 0x1
+	LOCK_UN = 0x8
+)