Commit 904e1136 authored by Ian Lance Taylor's avatar Ian Lance Taylor

runtime: add pipe/pipe2 on Solaris

This adds pipe/pipe2 on Solaris as they exist on other Unix systems.
They were not added previously because Solaris does not need them
for netpollBreak. They are added now in preparation for using pipes
in TestSignalM.

Updates #35276

Change-Id: I53dfdf077430153155f0a79715af98b0972a841c
Reviewed-on: https://go-review.googlesource.com/c/go/+/206077
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent f6ff806e
......@@ -13,6 +13,7 @@ const (
_ETIMEDOUT = 0x91
_EWOULDBLOCK = 0xb
_EINPROGRESS = 0x96
_ENOSYS = 0x59
_PROT_NONE = 0x0
_PROT_READ = 0x1
......@@ -91,6 +92,7 @@ const (
_MAXHOSTNAMELEN = 0x100
_O_NONBLOCK = 0x80
_O_CLOEXEC = 0x800000
_FD_CLOEXEC = 0x1
_F_GETFL = 0x3
_F_SETFL = 0x4
......
......@@ -43,6 +43,7 @@ const (
ETIMEDOUT = C.ETIMEDOUT
EWOULDBLOCK = C.EWOULDBLOCK
EINPROGRESS = C.EINPROGRESS
ENOSYS = C.ENOSYS
PROT_NONE = C.PROT_NONE
PROT_READ = C.PROT_READ
......@@ -120,6 +121,7 @@ const (
MAXHOSTNAMELEN = C.MAXHOSTNAMELEN
O_NONBLOCK = C.O_NONBLOCK
O_CLOEXEC = C.O_CLOEXEC
FD_CLOEXEC = C.FD_CLOEXEC
F_GETFL = C.F_GETFL
F_SETFL = C.F_SETFL
......
......@@ -2,11 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build aix darwin dragonfly freebsd linux netbsd openbsd
package runtime
var NonblockingPipe = nonblockingPipe
var Pipe = pipe
var SetNonblock = setNonblock
var Closeonexec = closeonexec
func Fcntl(fd, cmd, arg uintptr) (uintptr, uintptr) {
return sysvicall3Err(&libc_fcntl, fd, cmd, arg)
}
......@@ -6,6 +6,11 @@
package runtime
var NonblockingPipe = nonblockingPipe
var Pipe = pipe
var SetNonblock = setNonblock
var Closeonexec = closeonexec
func sigismember(mask *sigset, i int) bool {
clear := *mask
sigdelset(&clear, i)
......
......@@ -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
package runtime_test
import (
......@@ -9,8 +11,7 @@ import (
"syscall"
)
// We can't call syscall.Syscall on AIX. Therefore, fcntl is exported from the
// runtime in export_aix_test.go.
// Call fcntl libc function rather than calling syscall.
func fcntl(fd uintptr, cmd int, arg uintptr) (uintptr, syscall.Errno) {
res, errno := runtime.Fcntl(fd, uintptr(cmd), arg)
return res, syscall.Errno(errno)
......
......@@ -2,13 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build freebsd linux netbsd openbsd
// +build freebsd linux netbsd openbsd solaris
package runtime
func pipe() (r, w int32, errno int32)
func pipe2(flags int32) (r, w int32, errno int32)
func nonblockingPipe() (r, w int32, errno int32) {
r, w, errno = pipe2(_O_NONBLOCK | _O_CLOEXEC)
if errno == -_ENOSYS {
......
......@@ -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 darwin dragonfly freebsd linux netbsd openbsd
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package runtime_test
......
......@@ -46,6 +46,8 @@ import (
//go:cgo_import_dynamic libc_sysconf sysconf "libc.so"
//go:cgo_import_dynamic libc_usleep usleep "libc.so"
//go:cgo_import_dynamic libc_write write "libc.so"
//go:cgo_import_dynamic libc_pipe pipe "libc.so"
//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
//go:linkname libc____errno libc____errno
//go:linkname libc_clock_gettime libc_clock_gettime
......@@ -80,6 +82,8 @@ import (
//go:linkname libc_sysconf libc_sysconf
//go:linkname libc_usleep libc_usleep
//go:linkname libc_write libc_write
//go:linkname libc_pipe libc_pipe
//go:linkname libc_pipe2 libc_pipe2
var (
libc____errno,
......@@ -114,7 +118,9 @@ var (
libc_sigprocmask,
libc_sysconf,
libc_usleep,
libc_write libcFunc
libc_write,
libc_pipe,
libc_pipe2 libcFunc
)
var sigset_all = sigset{[4]uint32{^uint32(0), ^uint32(0), ^uint32(0), ^uint32(0)}}
......@@ -530,6 +536,31 @@ func write1(fd uintptr, buf unsafe.Pointer, nbyte int32) int32 {
return -int32(err)
}
//go:nosplit
func pipe() (r, w int32, errno int32) {
var p [2]int32
_, e := sysvicall1Err(&libc_pipe, uintptr(noescape(unsafe.Pointer(&p))))
return p[0], p[1], int32(e)
}
//go:nosplit
func pipe2(flags int32) (r, w int32, errno int32) {
var p [2]int32
_, e := sysvicall2Err(&libc_pipe2, uintptr(noescape(unsafe.Pointer(&p))), uintptr(flags))
return p[0], p[1], int32(e)
}
//go:nosplit
func closeonexec(fd int32) {
fcntl(fd, _F_SETFD, _FD_CLOEXEC)
}
//go:nosplit
func setNonblock(fd int32) {
flags := fcntl(fd, _F_GETFL, 0)
fcntl(fd, _F_SETFL, flags|_O_NONBLOCK)
}
func osyield1()
//go:nosplit
......
......@@ -40,6 +40,9 @@ func kqueue() int32
//go:noescape
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
func pipe() (r, w int32, errno int32)
func pipe2(flags int32) (r, w int32, errno int32)
func closeonexec(fd int32)
func setNonblock(fd int32)
......
......@@ -374,6 +374,8 @@ func raiseproc(sig uint32)
func sched_getaffinity(pid, len uintptr, buf *byte) int32
func osyield()
func pipe() (r, w int32, errno int32)
func pipe2(flags int32) (r, w int32, errno int32)
func setNonblock(fd int32)
//go:nosplit
......
......@@ -71,6 +71,9 @@ func kqueue() int32
//go:noescape
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
func pipe() (r, w int32, errno int32)
func pipe2(flags int32) (r, w int32, errno int32)
func closeonexec(fd int32)
func setNonblock(fd int32)
......
......@@ -62,6 +62,9 @@ func kqueue() int32
//go:noescape
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
func pipe() (r, w int32, errno int32)
func pipe2(flags int32) (r, w int32, errno int32)
func closeonexec(fd int32)
func setNonblock(fd int32)
......
......@@ -63,6 +63,15 @@ func sysvicall0(fn *libcFunc) uintptr {
//go:nosplit
func sysvicall1(fn *libcFunc, a1 uintptr) uintptr {
r1, _ := sysvicall1Err(fn, a1)
return r1
}
//go:nosplit
// sysvicall1Err returns both the system call result and the errno value.
// This is used by sysvicall1 and pipe.
func sysvicall1Err(fn *libcFunc, a1 uintptr) (r1, err uintptr) {
// Leave caller's PC/SP around for traceback.
gp := getg()
var mp *m
......@@ -88,11 +97,21 @@ func sysvicall1(fn *libcFunc, a1 uintptr) uintptr {
if mp != nil {
mp.libcallsp = 0
}
return libcall.r1
return libcall.r1, libcall.err
}
//go:nosplit
func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr {
r1, _ := sysvicall2Err(fn, a1, a2)
return r1
}
//go:nosplit
//go:cgo_unsafe_args
// sysvicall2Err returns both the system call result and the errno value.
// This is used by sysvicall2 and pipe2.
func sysvicall2Err(fn *libcFunc, a1, a2 uintptr) (uintptr, uintptr) {
// Leave caller's PC/SP around for traceback.
gp := getg()
var mp *m
......@@ -117,7 +136,7 @@ func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr {
if mp != nil {
mp.libcallsp = 0
}
return libcall.r1
return libcall.r1, libcall.err
}
//go:nosplit
......
......@@ -16,7 +16,6 @@ var (
libc_gethostname,
libc_getpid,
libc_ioctl,
libc_pipe,
libc_setgid,
libc_setgroups,
libc_setsid,
......
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