From: Mikio Hara Date: Sat, 1 Oct 2016 10:20:32 +0000 (+0900) Subject: syscall: fix Send{msg,msgN}, Recvmsg and control message handling on solaris X-Git-Tag: go1.8beta1~1063 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=89c4cbd7acc36cf627746f379f0cc002b5b60383;p=gostls13.git syscall: fix Send{msg,msgN}, Recvmsg and control message handling on solaris This change switches the use of socket implementation from the conventional SUS-based one to the latest POSIX-based one to make socket control message work correctly on Solaris. It looks like those two implementations, Socket over TLI/XTI and Socket, have different semantics in details but it wouldn't hurt the existing applications because the exposed syscall API doesn't support socket properties related to such a protocol independent application framework. Fixes #7402. Change-Id: I45a4e782d606bfbebe1404086c50a8c69af53461 Reviewed-on: https://go-review.googlesource.com/30171 Reviewed-by: Ian Lance Taylor --- diff --git a/src/syscall/sockcmsg_unix.go b/src/syscall/sockcmsg_unix.go index bc4caf54a2..5712bf13f2 100644 --- a/src/syscall/sockcmsg_unix.go +++ b/src/syscall/sockcmsg_unix.go @@ -13,9 +13,10 @@ import "unsafe" // Round the length of a raw sockaddr up to align it properly. func cmsgAlignOf(salen int) int { salign := sizeofPtr - // NOTE: It seems like 64-bit Darwin and DragonFly BSD kernels - // still require 32-bit aligned access to network subsystem. - if darwin64Bit || dragonfly64Bit { + // NOTE: It seems like 64-bit Darwin, DragonFly BSD and + // Solaris kernels still require 32-bit aligned access to + // network subsystem. + if darwin64Bit || dragonfly64Bit || solaris64Bit { salign = 4 } return (salen + salign - 1) & ^(salign - 1) diff --git a/src/syscall/syscall_solaris.go b/src/syscall/syscall_solaris.go index 8de9161257..61f550e959 100644 --- a/src/syscall/syscall_solaris.go +++ b/src/syscall/syscall_solaris.go @@ -370,6 +370,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from iov.SetLen(1) } msg.Accrights = (*int8)(unsafe.Pointer(&oob[0])) + msg.Accrightslen = int32(len(oob)) } msg.Iov = &iov msg.Iovlen = 1 @@ -389,7 +390,7 @@ func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { return } -//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.sendmsg +//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_sendmsg func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { var ptr unsafe.Pointer @@ -416,6 +417,7 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) iov.SetLen(1) } msg.Accrights = (*int8)(unsafe.Pointer(&oob[0])) + msg.Accrightslen = int32(len(oob)) } msg.Iov = &iov msg.Iovlen = 1 @@ -458,7 +460,7 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) //sys Kill(pid int, signum Signal) (err error) //sys Lchown(path string, uid int, gid int) (err error) //sys Link(path string, link string) (err error) -//sys Listen(s int, backlog int) (err error) = libsocket.listen +//sys Listen(s int, backlog int) (err error) = libsocket.__xnet_listen //sys Lstat(path string, stat *Stat_t) (err error) //sys Mkdir(path string, mode uint32) (err error) //sys Mknod(path string, mode uint32, dev int) (err error) @@ -493,20 +495,20 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) //sys Umask(newmask int) (oldmask int) //sys Unlink(path string) (err error) //sys Utimes(path string, times *[2]Timeval) (err error) -//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.bind -//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.connect +//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_bind +//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_connect //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys munmap(addr uintptr, length uintptr) (err error) -//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.sendto -//sys socket(domain int, typ int, proto int) (fd int, err error) = libsocket.socket -//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.socketpair +//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_sendto +//sys socket(domain int, typ int, proto int) (fd int, err error) = libsocket.__xnet_socket +//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.__xnet_socketpair //sys write(fd int, p []byte) (n int, err error) -//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.getsockopt +//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.__xnet_getsockopt //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getpeername //sys getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getsockname //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libsocket.setsockopt //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom -//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.recvmsg +//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_recvmsg func readlen(fd int, buf *byte, nbuf int) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_read)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0) diff --git a/src/syscall/syscall_unix.go b/src/syscall/syscall_unix.go index 4dae9d9b18..442f558ffa 100644 --- a/src/syscall/syscall_unix.go +++ b/src/syscall/syscall_unix.go @@ -23,6 +23,7 @@ const ( darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8 dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8 netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4 + solaris64Bit = runtime.GOOS == "solaris" && sizeofPtr == 8 ) func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) diff --git a/src/syscall/syscall_unix_test.go b/src/syscall/syscall_unix_test.go index 0be07c6e90..2f25d18bca 100644 --- a/src/syscall/syscall_unix_test.go +++ b/src/syscall/syscall_unix_test.go @@ -125,12 +125,6 @@ func TestFcntlFlock(t *testing.T) { // "-test.run=^TestPassFD$" and an environment variable used to signal // that the test should become the child process instead. func TestPassFD(t *testing.T) { - switch runtime.GOOS { - case "solaris": - // TODO(aram): Figure out why ReadMsgUnix is returning empty message. - t.Skip("skipping test on solaris, see issue 7402") - } - testenv.MustHaveExec(t) if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" { diff --git a/src/syscall/zsyscall_solaris_amd64.go b/src/syscall/zsyscall_solaris_amd64.go index ebdeb92bfb..89ab48bc17 100644 --- a/src/syscall/zsyscall_solaris_amd64.go +++ b/src/syscall/zsyscall_solaris_amd64.go @@ -12,7 +12,7 @@ import "unsafe" //go:cgo_import_dynamic libc_setgroups setgroups "libc.so" //go:cgo_import_dynamic libc_fcntl fcntl "libc.so" //go:cgo_import_dynamic libc_accept accept "libsocket.so" -//go:cgo_import_dynamic libc_sendmsg sendmsg "libsocket.so" +//go:cgo_import_dynamic libc___xnet_sendmsg __xnet_sendmsg "libsocket.so" //go:cgo_import_dynamic libc_Access access "libc.so" //go:cgo_import_dynamic libc_Adjtime adjtime "libc.so" //go:cgo_import_dynamic libc_Chdir chdir "libc.so" @@ -40,7 +40,7 @@ import "unsafe" //go:cgo_import_dynamic libc_Kill kill "libc.so" //go:cgo_import_dynamic libc_Lchown lchown "libc.so" //go:cgo_import_dynamic libc_Link link "libc.so" -//go:cgo_import_dynamic libc_listen listen "libsocket.so" +//go:cgo_import_dynamic libc___xnet_listen __xnet_listen "libsocket.so" //go:cgo_import_dynamic libc_Lstat lstat "libc.so" //go:cgo_import_dynamic libc_Mkdir mkdir "libc.so" //go:cgo_import_dynamic libc_Mknod mknod "libc.so" @@ -75,27 +75,27 @@ import "unsafe" //go:cgo_import_dynamic libc_Umask umask "libc.so" //go:cgo_import_dynamic libc_Unlink unlink "libc.so" //go:cgo_import_dynamic libc_Utimes utimes "libc.so" -//go:cgo_import_dynamic libc_bind bind "libsocket.so" -//go:cgo_import_dynamic libc_connect connect "libsocket.so" +//go:cgo_import_dynamic libc___xnet_bind __xnet_bind "libsocket.so" +//go:cgo_import_dynamic libc___xnet_connect __xnet_connect "libsocket.so" //go:cgo_import_dynamic libc_mmap mmap "libc.so" //go:cgo_import_dynamic libc_munmap munmap "libc.so" -//go:cgo_import_dynamic libc_sendto sendto "libsocket.so" -//go:cgo_import_dynamic libc_socket socket "libsocket.so" -//go:cgo_import_dynamic libc_socketpair socketpair "libsocket.so" +//go:cgo_import_dynamic libc___xnet_sendto __xnet_sendto "libsocket.so" +//go:cgo_import_dynamic libc___xnet_socket __xnet_socket "libsocket.so" +//go:cgo_import_dynamic libc___xnet_socketpair __xnet_socketpair "libsocket.so" //go:cgo_import_dynamic libc_write write "libc.so" -//go:cgo_import_dynamic libc_getsockopt getsockopt "libsocket.so" +//go:cgo_import_dynamic libc___xnet_getsockopt __xnet_getsockopt "libsocket.so" //go:cgo_import_dynamic libc_getpeername getpeername "libsocket.so" //go:cgo_import_dynamic libc_getsockname getsockname "libsocket.so" //go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so" //go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so" -//go:cgo_import_dynamic libc_recvmsg recvmsg "libsocket.so" +//go:cgo_import_dynamic libc___xnet_recvmsg __xnet_recvmsg "libsocket.so" //go:linkname libc_Getcwd libc_Getcwd //go:linkname libc_getgroups libc_getgroups //go:linkname libc_setgroups libc_setgroups //go:linkname libc_fcntl libc_fcntl //go:linkname libc_accept libc_accept -//go:linkname libc_sendmsg libc_sendmsg +//go:linkname libc___xnet_sendmsg libc___xnet_sendmsg //go:linkname libc_Access libc_Access //go:linkname libc_Adjtime libc_Adjtime //go:linkname libc_Chdir libc_Chdir @@ -123,7 +123,7 @@ import "unsafe" //go:linkname libc_Kill libc_Kill //go:linkname libc_Lchown libc_Lchown //go:linkname libc_Link libc_Link -//go:linkname libc_listen libc_listen +//go:linkname libc___xnet_listen libc___xnet_listen //go:linkname libc_Lstat libc_Lstat //go:linkname libc_Mkdir libc_Mkdir //go:linkname libc_Mknod libc_Mknod @@ -158,20 +158,20 @@ import "unsafe" //go:linkname libc_Umask libc_Umask //go:linkname libc_Unlink libc_Unlink //go:linkname libc_Utimes libc_Utimes -//go:linkname libc_bind libc_bind -//go:linkname libc_connect libc_connect +//go:linkname libc___xnet_bind libc___xnet_bind +//go:linkname libc___xnet_connect libc___xnet_connect //go:linkname libc_mmap libc_mmap //go:linkname libc_munmap libc_munmap -//go:linkname libc_sendto libc_sendto -//go:linkname libc_socket libc_socket -//go:linkname libc_socketpair libc_socketpair +//go:linkname libc___xnet_sendto libc___xnet_sendto +//go:linkname libc___xnet_socket libc___xnet_socket +//go:linkname libc___xnet_socketpair libc___xnet_socketpair //go:linkname libc_write libc_write -//go:linkname libc_getsockopt libc_getsockopt +//go:linkname libc___xnet_getsockopt libc___xnet_getsockopt //go:linkname libc_getpeername libc_getpeername //go:linkname libc_getsockname libc_getsockname //go:linkname libc_setsockopt libc_setsockopt //go:linkname libc_recvfrom libc_recvfrom -//go:linkname libc_recvmsg libc_recvmsg +//go:linkname libc___xnet_recvmsg libc___xnet_recvmsg type libcFunc uintptr @@ -181,7 +181,7 @@ var ( libc_setgroups, libc_fcntl, libc_accept, - libc_sendmsg, + libc___xnet_sendmsg, libc_Access, libc_Adjtime, libc_Chdir, @@ -209,7 +209,7 @@ var ( libc_Kill, libc_Lchown, libc_Link, - libc_listen, + libc___xnet_listen, libc_Lstat, libc_Mkdir, libc_Mknod, @@ -244,20 +244,20 @@ var ( libc_Umask, libc_Unlink, libc_Utimes, - libc_bind, - libc_connect, + libc___xnet_bind, + libc___xnet_connect, libc_mmap, libc_munmap, - libc_sendto, - libc_socket, - libc_socketpair, + libc___xnet_sendto, + libc___xnet_socket, + libc___xnet_socketpair, libc_write, - libc_getsockopt, + libc___xnet_getsockopt, libc_getpeername, libc_getsockname, libc_setsockopt, libc_recvfrom, - libc_recvmsg libcFunc + libc___xnet_recvmsg libcFunc ) func Getcwd(buf []byte) (n int, err error) { @@ -309,7 +309,7 @@ func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { } func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_sendmsg)), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc___xnet_sendmsg)), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) n = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -575,7 +575,7 @@ func Link(path string, link string) (err error) { } func Listen(s int, backlog int) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_listen)), 2, uintptr(s), uintptr(backlog), 0, 0, 0, 0) + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc___xnet_listen)), 2, uintptr(s), uintptr(backlog), 0, 0, 0, 0) if e1 != 0 { err = errnoErr(e1) } @@ -968,7 +968,7 @@ func Utimes(path string, times *[2]Timeval) (err error) { } func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_bind)), 3, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc___xnet_bind)), 3, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) if e1 != 0 { err = errnoErr(e1) } @@ -976,7 +976,7 @@ func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { } func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_connect)), 3, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc___xnet_connect)), 3, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) if e1 != 0 { err = errnoErr(e1) } @@ -1005,7 +1005,7 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) ( if len(buf) > 0 { _p0 = &buf[0] } - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_sendto)), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc___xnet_sendto)), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) if e1 != 0 { err = errnoErr(e1) } @@ -1013,7 +1013,7 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) ( } func socket(domain int, typ int, proto int) (fd int, err error) { - r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_socket)), 3, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0) + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc___xnet_socket)), 3, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0) fd = int(r0) if e1 != 0 { err = errnoErr(e1) @@ -1022,7 +1022,7 @@ func socket(domain int, typ int, proto int) (fd int, err error) { } func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { - _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&libc_socketpair)), 4, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) + _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&libc___xnet_socketpair)), 4, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) if e1 != 0 { err = errnoErr(e1) } @@ -1043,7 +1043,7 @@ func write(fd int, p []byte) (n int, err error) { } func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_getsockopt)), 5, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc___xnet_getsockopt)), 5, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) if e1 != 0 { err = errnoErr(e1) } @@ -1088,7 +1088,7 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl } func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { - r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_recvmsg)), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc___xnet_recvmsg)), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) n = int(r0) if e1 != 0 { err = errnoErr(e1)