unix: implement recvmsgRaw and sendmsgN on aix
This allows using RecvmsgBuffers and SendmsgBuffers on aix in x/net.
For golang/go#54099
Change-Id: Ib21c59244c9d74b826f4fc8ba3314e3602fd9a8a
Reviewed-on: https://go-review.googlesource.com/c/sys/+/419396
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
Auto-Submit: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/unix/syscall_aix.go b/unix/syscall_aix.go
index ac579c6..e2a30e8 100644
--- a/unix/syscall_aix.go
+++ b/unix/syscall_aix.go
@@ -218,13 +218,62 @@
}
func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
- // Recvmsg not implemented on AIX
- return -1, -1, -1, ENOSYS
+ var msg Msghdr
+ msg.Name = (*byte)(unsafe.Pointer(rsa))
+ msg.Namelen = uint32(SizeofSockaddrAny)
+ var dummy byte
+ if len(oob) > 0 {
+ // receive at least one normal byte
+ if emptyIovecs(iov) {
+ var iova [1]Iovec
+ iova[0].Base = &dummy
+ iova[0].SetLen(1)
+ iov = iova[:]
+ }
+ msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+ msg.SetControllen(len(oob))
+ }
+ if len(iov) > 0 {
+ msg.Iov = &iov[0]
+ msg.SetIovlen(len(iov))
+ }
+ if n, err = recvmsg(fd, &msg, flags); n == -1 {
+ return
+ }
+ oobn = int(msg.Controllen)
+ recvflags = int(msg.Flags)
+ return
}
func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
- // SendmsgN not implemented on AIX
- return -1, ENOSYS
+ var msg Msghdr
+ msg.Name = (*byte)(unsafe.Pointer(ptr))
+ msg.Namelen = uint32(salen)
+ var dummy byte
+ var empty bool
+ if len(oob) > 0 {
+ // send at least one normal byte
+ empty := emptyIovecs(iov)
+ if empty {
+ var iova [1]Iovec
+ iova[0].Base = &dummy
+ iova[0].SetLen(1)
+ iov = iova[:]
+ }
+ msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+ msg.SetControllen(len(oob))
+ }
+ if len(iov) > 0 {
+ msg.Iov = &iov[0]
+ msg.SetIovlen(len(iov))
+ }
+ if n, err = sendmsg(fd, &msg, flags); err != nil {
+ return 0, err
+ }
+ if len(oob) > 0 && empty {
+ n = 0
+ }
+ return n, nil
}
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
diff --git a/unix/syscall_unix_test.go b/unix/syscall_unix_test.go
index c20afbe..f2c0ed8 100644
--- a/unix/syscall_unix_test.go
+++ b/unix/syscall_unix_test.go
@@ -957,10 +957,6 @@
}
func TestSendmsgBuffers(t *testing.T) {
- if runtime.GOOS == "aix" {
- t.Skipf("SendmsgBuffers not supported on %s", runtime.GOOS)
- }
-
fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM, 0)
if err != nil {
t.Fatal(err)