unix: add Pipe2 for solaris

We already implement Pipe2 for illumos and it seems solaris provides the
pipe2 syscall as well, see
https://docs.oracle.com/cd/E88353_01/html/E37841/pipe2-2.html.

Fixes golang/go#40613

Change-Id: I135cb1e78e6c67567d30d7eed266d00ef8fd6c3a
Reviewed-on: https://go-review.googlesource.com/c/sys/+/283032
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matt Layher <mdlayher@gmail.com>
diff --git a/unix/syscall_illumos.go b/unix/syscall_illumos.go
index bbc4f3e..7a2d412 100644
--- a/unix/syscall_illumos.go
+++ b/unix/syscall_illumos.go
@@ -75,16 +75,3 @@
 	}
 	return
 }
-
-//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
-
-func Pipe2(p []int, flags int) error {
-	if len(p) != 2 {
-		return EINVAL
-	}
-	var pp [2]_C_int
-	err := pipe2(&pp, flags)
-	p[0] = int(pp[0])
-	p[1] = int(pp[1])
-	return err
-}
diff --git a/unix/syscall_solaris.go b/unix/syscall_solaris.go
index fee6e99..184786e 100644
--- a/unix/syscall_solaris.go
+++ b/unix/syscall_solaris.go
@@ -68,6 +68,19 @@
 	return nil
 }
 
+//sysnb	pipe2(p *[2]_C_int, flags int) (err error)
+
+func Pipe2(p []int, flags int) error {
+	if len(p) != 2 {
+		return EINVAL
+	}
+	var pp [2]_C_int
+	err := pipe2(&pp, flags)
+	p[0] = int(pp[0])
+	p[1] = int(pp[1])
+	return err
+}
+
 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
 	if sa.Port < 0 || sa.Port > 0xFFFF {
 		return nil, 0, EINVAL
diff --git a/unix/syscall_solaris_test.go b/unix/syscall_solaris_test.go
index d3e7d2b..ae2c40c 100644
--- a/unix/syscall_solaris_test.go
+++ b/unix/syscall_solaris_test.go
@@ -13,6 +13,48 @@
 	"golang.org/x/sys/unix"
 )
 
+func TestPipe2(t *testing.T) {
+	const s = "hello"
+	var pipes [2]int
+	err := unix.Pipe2(pipes[:], 0)
+	if err != nil {
+		t.Fatalf("pipe2: %v", err)
+	}
+	r := pipes[0]
+	w := pipes[1]
+	go func() {
+		n, err := unix.Write(w, []byte(s))
+		if err != nil {
+			t.Errorf("bad write: %v", err)
+			return
+		}
+		if n != len(s) {
+			t.Errorf("bad write count: %d", n)
+			return
+		}
+		err = unix.Close(w)
+		if err != nil {
+			t.Errorf("bad close: %v", err)
+			return
+		}
+	}()
+	var buf [10 + len(s)]byte
+	n, err := unix.Read(r, buf[:])
+	if err != nil {
+		t.Fatalf("bad read: %v", err)
+	}
+	if n != len(s) {
+		t.Fatalf("bad read count: %d", n)
+	}
+	if string(buf[:n]) != s {
+		t.Fatalf("bad contents: %s", string(buf[:n]))
+	}
+	err = unix.Close(r)
+	if err != nil {
+		t.Fatalf("bad close: %v", err)
+	}
+}
+
 func TestStatvfs(t *testing.T) {
 	if err := unix.Statvfs("", nil); err == nil {
 		t.Fatal(`Statvfs("") expected failure`)
diff --git a/unix/zsyscall_illumos_amd64.go b/unix/zsyscall_illumos_amd64.go
index d3af083..665dd9e 100644
--- a/unix/zsyscall_illumos_amd64.go
+++ b/unix/zsyscall_illumos_amd64.go
@@ -14,22 +14,19 @@
 //go:cgo_import_dynamic libc_writev writev "libc.so"
 //go:cgo_import_dynamic libc_pwritev pwritev "libc.so"
 //go:cgo_import_dynamic libc_accept4 accept4 "libsocket.so"
-//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
 
 //go:linkname procreadv libc_readv
 //go:linkname procpreadv libc_preadv
 //go:linkname procwritev libc_writev
 //go:linkname procpwritev libc_pwritev
 //go:linkname procaccept4 libc_accept4
-//go:linkname procpipe2 libc_pipe2
 
 var (
 	procreadv,
 	procpreadv,
 	procwritev,
 	procpwritev,
-	procaccept4,
-	procpipe2 syscallFunc
+	procaccept4 syscallFunc
 )
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -102,13 +99,3 @@
 	}
 	return
 }
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procpipe2)), 2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/unix/zsyscall_solaris_amd64.go b/unix/zsyscall_solaris_amd64.go
index a96165d..6dbb837 100644
--- a/unix/zsyscall_solaris_amd64.go
+++ b/unix/zsyscall_solaris_amd64.go
@@ -11,6 +11,7 @@
 )
 
 //go:cgo_import_dynamic libc_pipe pipe "libc.so"
+//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
 //go:cgo_import_dynamic libc_getsockname getsockname "libsocket.so"
 //go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
 //go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
@@ -140,6 +141,7 @@
 //go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so"
 
 //go:linkname procpipe libc_pipe
+//go:linkname procpipe2 libc_pipe2
 //go:linkname procgetsockname libc_getsockname
 //go:linkname procGetcwd libc_getcwd
 //go:linkname procgetgroups libc_getgroups
@@ -270,6 +272,7 @@
 
 var (
 	procpipe,
+	procpipe2,
 	procgetsockname,
 	procGetcwd,
 	procgetgroups,
@@ -412,6 +415,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procpipe2)), 2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
 	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetsockname)), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
 	if e1 != 0 {