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 ( ...@@ -13,6 +13,7 @@ const (
_ETIMEDOUT = 0x91 _ETIMEDOUT = 0x91
_EWOULDBLOCK = 0xb _EWOULDBLOCK = 0xb
_EINPROGRESS = 0x96 _EINPROGRESS = 0x96
_ENOSYS = 0x59
_PROT_NONE = 0x0 _PROT_NONE = 0x0
_PROT_READ = 0x1 _PROT_READ = 0x1
...@@ -91,6 +92,7 @@ const ( ...@@ -91,6 +92,7 @@ const (
_MAXHOSTNAMELEN = 0x100 _MAXHOSTNAMELEN = 0x100
_O_NONBLOCK = 0x80 _O_NONBLOCK = 0x80
_O_CLOEXEC = 0x800000
_FD_CLOEXEC = 0x1 _FD_CLOEXEC = 0x1
_F_GETFL = 0x3 _F_GETFL = 0x3
_F_SETFL = 0x4 _F_SETFL = 0x4
......
...@@ -43,6 +43,7 @@ const ( ...@@ -43,6 +43,7 @@ const (
ETIMEDOUT = C.ETIMEDOUT ETIMEDOUT = C.ETIMEDOUT
EWOULDBLOCK = C.EWOULDBLOCK EWOULDBLOCK = C.EWOULDBLOCK
EINPROGRESS = C.EINPROGRESS EINPROGRESS = C.EINPROGRESS
ENOSYS = C.ENOSYS
PROT_NONE = C.PROT_NONE PROT_NONE = C.PROT_NONE
PROT_READ = C.PROT_READ PROT_READ = C.PROT_READ
...@@ -120,6 +121,7 @@ const ( ...@@ -120,6 +121,7 @@ const (
MAXHOSTNAMELEN = C.MAXHOSTNAMELEN MAXHOSTNAMELEN = C.MAXHOSTNAMELEN
O_NONBLOCK = C.O_NONBLOCK O_NONBLOCK = C.O_NONBLOCK
O_CLOEXEC = C.O_CLOEXEC
FD_CLOEXEC = C.FD_CLOEXEC FD_CLOEXEC = C.FD_CLOEXEC
F_GETFL = C.F_GETFL F_GETFL = C.F_GETFL
F_SETFL = C.F_SETFL F_SETFL = C.F_SETFL
......
...@@ -2,11 +2,8 @@ ...@@ -2,11 +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 darwin dragonfly freebsd linux netbsd openbsd
package runtime package runtime
var NonblockingPipe = nonblockingPipe func Fcntl(fd, cmd, arg uintptr) (uintptr, uintptr) {
var Pipe = pipe return sysvicall3Err(&libc_fcntl, fd, cmd, arg)
var SetNonblock = setNonblock }
var Closeonexec = closeonexec
...@@ -6,6 +6,11 @@ ...@@ -6,6 +6,11 @@
package runtime package runtime
var NonblockingPipe = nonblockingPipe
var Pipe = pipe
var SetNonblock = setNonblock
var Closeonexec = closeonexec
func sigismember(mask *sigset, i int) bool { func sigismember(mask *sigset, i int) bool {
clear := *mask clear := *mask
sigdelset(&clear, i) sigdelset(&clear, i)
......
...@@ -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
package runtime_test package runtime_test
import ( import (
...@@ -9,8 +11,7 @@ import ( ...@@ -9,8 +11,7 @@ import (
"syscall" "syscall"
) )
// We can't call syscall.Syscall on AIX. Therefore, fcntl is exported from the // Call fcntl libc function rather than calling syscall.
// runtime in export_aix_test.go.
func fcntl(fd uintptr, cmd int, arg uintptr) (uintptr, syscall.Errno) { func fcntl(fd uintptr, cmd int, arg uintptr) (uintptr, syscall.Errno) {
res, errno := runtime.Fcntl(fd, uintptr(cmd), arg) res, errno := runtime.Fcntl(fd, uintptr(cmd), arg)
return res, syscall.Errno(errno) return res, syscall.Errno(errno)
......
...@@ -2,13 +2,10 @@ ...@@ -2,13 +2,10 @@
// 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 freebsd linux netbsd openbsd // +build freebsd linux netbsd openbsd solaris
package runtime 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) { func nonblockingPipe() (r, w int32, errno int32) {
r, w, errno = pipe2(_O_NONBLOCK | _O_CLOEXEC) r, w, errno = pipe2(_O_NONBLOCK | _O_CLOEXEC)
if errno == -_ENOSYS { if errno == -_ENOSYS {
......
...@@ -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 aix darwin dragonfly freebsd linux netbsd openbsd // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package runtime_test package runtime_test
......
...@@ -46,6 +46,8 @@ import ( ...@@ -46,6 +46,8 @@ import (
//go:cgo_import_dynamic libc_sysconf sysconf "libc.so" //go:cgo_import_dynamic libc_sysconf sysconf "libc.so"
//go:cgo_import_dynamic libc_usleep usleep "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_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____errno libc____errno
//go:linkname libc_clock_gettime libc_clock_gettime //go:linkname libc_clock_gettime libc_clock_gettime
...@@ -80,6 +82,8 @@ import ( ...@@ -80,6 +82,8 @@ import (
//go:linkname libc_sysconf libc_sysconf //go:linkname libc_sysconf libc_sysconf
//go:linkname libc_usleep libc_usleep //go:linkname libc_usleep libc_usleep
//go:linkname libc_write libc_write //go:linkname libc_write libc_write
//go:linkname libc_pipe libc_pipe
//go:linkname libc_pipe2 libc_pipe2
var ( var (
libc____errno, libc____errno,
...@@ -114,7 +118,9 @@ var ( ...@@ -114,7 +118,9 @@ var (
libc_sigprocmask, libc_sigprocmask,
libc_sysconf, libc_sysconf,
libc_usleep, 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)}} 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 { ...@@ -530,6 +536,31 @@ func write1(fd uintptr, buf unsafe.Pointer, nbyte int32) int32 {
return -int32(err) 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() func osyield1()
//go:nosplit //go:nosplit
......
...@@ -40,6 +40,9 @@ func kqueue() int32 ...@@ -40,6 +40,9 @@ func kqueue() int32
//go:noescape //go:noescape
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 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 closeonexec(fd int32)
func setNonblock(fd int32) func setNonblock(fd int32)
......
...@@ -374,6 +374,8 @@ func raiseproc(sig uint32) ...@@ -374,6 +374,8 @@ func raiseproc(sig uint32)
func sched_getaffinity(pid, len uintptr, buf *byte) int32 func sched_getaffinity(pid, len uintptr, buf *byte) int32
func osyield() func osyield()
func pipe() (r, w int32, errno int32)
func pipe2(flags int32) (r, w int32, errno int32)
func setNonblock(fd int32) func setNonblock(fd int32)
//go:nosplit //go:nosplit
......
...@@ -71,6 +71,9 @@ func kqueue() int32 ...@@ -71,6 +71,9 @@ func kqueue() int32
//go:noescape //go:noescape
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 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 closeonexec(fd int32)
func setNonblock(fd int32) func setNonblock(fd int32)
......
...@@ -62,6 +62,9 @@ func kqueue() int32 ...@@ -62,6 +62,9 @@ func kqueue() int32
//go:noescape //go:noescape
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 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 closeonexec(fd int32)
func setNonblock(fd int32) func setNonblock(fd int32)
......
...@@ -63,6 +63,15 @@ func sysvicall0(fn *libcFunc) uintptr { ...@@ -63,6 +63,15 @@ func sysvicall0(fn *libcFunc) uintptr {
//go:nosplit //go:nosplit
func sysvicall1(fn *libcFunc, a1 uintptr) uintptr { 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. // Leave caller's PC/SP around for traceback.
gp := getg() gp := getg()
var mp *m var mp *m
...@@ -88,11 +97,21 @@ func sysvicall1(fn *libcFunc, a1 uintptr) uintptr { ...@@ -88,11 +97,21 @@ func sysvicall1(fn *libcFunc, a1 uintptr) uintptr {
if mp != nil { if mp != nil {
mp.libcallsp = 0 mp.libcallsp = 0
} }
return libcall.r1 return libcall.r1, libcall.err
} }
//go:nosplit //go:nosplit
func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr { 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. // Leave caller's PC/SP around for traceback.
gp := getg() gp := getg()
var mp *m var mp *m
...@@ -117,7 +136,7 @@ func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr { ...@@ -117,7 +136,7 @@ func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr {
if mp != nil { if mp != nil {
mp.libcallsp = 0 mp.libcallsp = 0
} }
return libcall.r1 return libcall.r1, libcall.err
} }
//go:nosplit //go:nosplit
......
...@@ -16,7 +16,6 @@ var ( ...@@ -16,7 +16,6 @@ var (
libc_gethostname, libc_gethostname,
libc_getpid, libc_getpid,
libc_ioctl, libc_ioctl,
libc_pipe,
libc_setgid, libc_setgid,
libc_setgroups, libc_setgroups,
libc_setsid, 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