]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: fix Send{msg,msgN}, Recvmsg and control message handling on solaris
authorMikio Hara <mikioh.mikioh@gmail.com>
Sat, 1 Oct 2016 10:20:32 +0000 (19:20 +0900)
committerMikio Hara <mikioh.mikioh@gmail.com>
Mon, 3 Oct 2016 23:53:42 +0000 (23:53 +0000)
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 <iant@golang.org>
src/syscall/sockcmsg_unix.go
src/syscall/syscall_solaris.go
src/syscall/syscall_unix.go
src/syscall/syscall_unix_test.go
src/syscall/zsyscall_solaris_amd64.go

index bc4caf54a29c99299fc5cbf26e8a5e39ed699987..5712bf13f223fca4468db96e7c3ed2b7a2da2c84 100644 (file)
@@ -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)
index 8de916125720792a4ec473d4f7d7a2c60a368fc8..61f550e95910b54e02c5837553889e5e7b8b549a 100644 (file)
@@ -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)
index 4dae9d9b18c9f543a4b5be1966d21bac57bb5c66..442f558ffa55251b54265e7f89dd535da9eb09ff 100644 (file)
@@ -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)
index 0be07c6e9049381095406b3f3e818219c5e847b9..2f25d18bca94df2b3bab7dc981043135765f8cff 100644 (file)
@@ -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" {
index ebdeb92bfb4ad2585f1f26d65ebb97f1b91e9845..89ab48bc177064cf8951f62f6c2af343b15de9ef 100644 (file)
@@ -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)