From: Ian Lance Taylor Date: Fri, 8 Nov 2019 05:04:53 +0000 (-0800) Subject: runtime: add pipe/pipe2 on Solaris X-Git-Tag: go1.14beta1~294 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=904e1136c226b2b6ca31969acbf90ae44ecf8dc0;p=gostls13.git 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 Reviewed-by: Brad Fitzpatrick --- diff --git a/src/runtime/defs1_solaris_amd64.go b/src/runtime/defs1_solaris_amd64.go index ee6c45e524..19e8a2512e 100644 --- a/src/runtime/defs1_solaris_amd64.go +++ b/src/runtime/defs1_solaris_amd64.go @@ -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 diff --git a/src/runtime/defs_solaris.go b/src/runtime/defs_solaris.go index f42adebee3..22df59094d 100644 --- a/src/runtime/defs_solaris.go +++ b/src/runtime/defs_solaris.go @@ -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 diff --git a/src/runtime/export_nbpipe_test.go b/src/runtime/export_solaris_test.go similarity index 50% rename from src/runtime/export_nbpipe_test.go rename to src/runtime/export_solaris_test.go index cf7863566a..e865c77691 100644 --- a/src/runtime/export_nbpipe_test.go +++ b/src/runtime/export_solaris_test.go @@ -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) +} diff --git a/src/runtime/export_unix_test.go b/src/runtime/export_unix_test.go index 5e59e406c6..375513337e 100644 --- a/src/runtime/export_unix_test.go +++ b/src/runtime/export_unix_test.go @@ -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) diff --git a/src/runtime/nbpipe_fcntl_aix_test.go b/src/runtime/nbpipe_fcntl_libc_test.go similarity index 76% rename from src/runtime/nbpipe_fcntl_aix_test.go rename to src/runtime/nbpipe_fcntl_libc_test.go index 4276ed5b53..70f4b8348b 100644 --- a/src/runtime/nbpipe_fcntl_aix_test.go +++ b/src/runtime/nbpipe_fcntl_libc_test.go @@ -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) diff --git a/src/runtime/nbpipe_pipe2.go b/src/runtime/nbpipe_pipe2.go index f4c862cbff..e3639d99b1 100644 --- a/src/runtime/nbpipe_pipe2.go +++ b/src/runtime/nbpipe_pipe2.go @@ -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 { diff --git a/src/runtime/nbpipe_test.go b/src/runtime/nbpipe_test.go index 00dc11e937..d739f57864 100644 --- a/src/runtime/nbpipe_test.go +++ b/src/runtime/nbpipe_test.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 darwin dragonfly freebsd linux netbsd openbsd +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris package runtime_test diff --git a/src/runtime/os3_solaris.go b/src/runtime/os3_solaris.go index 373c682f05..d6e36fbfbb 100644 --- a/src/runtime/os3_solaris.go +++ b/src/runtime/os3_solaris.go @@ -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 diff --git a/src/runtime/os_freebsd.go b/src/runtime/os_freebsd.go index 69e05b66a2..730973a202 100644 --- a/src/runtime/os_freebsd.go +++ b/src/runtime/os_freebsd.go @@ -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) diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go index 20b947f250..27c66f7449 100644 --- a/src/runtime/os_linux.go +++ b/src/runtime/os_linux.go @@ -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 diff --git a/src/runtime/os_netbsd.go b/src/runtime/os_netbsd.go index b50cf237fb..97106c7b9d 100644 --- a/src/runtime/os_netbsd.go +++ b/src/runtime/os_netbsd.go @@ -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) diff --git a/src/runtime/os_openbsd.go b/src/runtime/os_openbsd.go index f26b39575d..b486b83688 100644 --- a/src/runtime/os_openbsd.go +++ b/src/runtime/os_openbsd.go @@ -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) diff --git a/src/runtime/os_solaris.go b/src/runtime/os_solaris.go index d6c09156bd..89129e5f1a 100644 --- a/src/runtime/os_solaris.go +++ b/src/runtime/os_solaris.go @@ -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 diff --git a/src/runtime/syscall_solaris.go b/src/runtime/syscall_solaris.go index 35381801c5..76db54d274 100644 --- a/src/runtime/syscall_solaris.go +++ b/src/runtime/syscall_solaris.go @@ -16,7 +16,6 @@ var ( libc_gethostname, libc_getpid, libc_ioctl, - libc_pipe, libc_setgid, libc_setgroups, libc_setsid,