unix: add SockaddrUnix tests on linux
Follow the existing examples of the SockaddrTIPC and SockaddrL2TPIP{,6}
tests.
Handling of abstract socket addresses is different on linux than on
other platforms, thus these are currently linux-specific.
Change-Id: I66686d979e1dd317ab7a8a6dd85f98e670ad89b6
Reviewed-on: https://go-review.googlesource.com/c/sys/+/228764
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/unix/syscall_internal_linux_test.go b/unix/syscall_internal_linux_test.go
index 4dafac8..22199b2 100644
--- a/unix/syscall_internal_linux_test.go
+++ b/unix/syscall_internal_linux_test.go
@@ -8,6 +8,7 @@
import (
"reflect"
+ "strings"
"testing"
"unsafe"
)
@@ -137,6 +138,25 @@
skt: SocketSpec{domain: AF_INET6, typ: SOCK_DGRAM, protocol: IPPROTO_L2TP},
},
{
+ name: "AF_UNIX unnamed/abstract",
+ rsa: sockaddrUnixToAny(RawSockaddrUnix{
+ Family: AF_UNIX,
+ }),
+ sa: &SockaddrUnix{
+ Name: "@",
+ },
+ },
+ {
+ name: "AF_UNIX named",
+ rsa: sockaddrUnixToAny(RawSockaddrUnix{
+ Family: AF_UNIX,
+ Path: [108]int8{'g', 'o', 'p', 'h', 'e', 'r'},
+ }),
+ sa: &SockaddrUnix{
+ Name: "gopher",
+ },
+ },
+ {
name: "AF_MAX EAFNOSUPPORT",
rsa: &RawSockaddrAny{
Addr: RawSockaddr{
@@ -373,6 +393,76 @@
}
}
+func TestSockaddrUnix_sockaddr(t *testing.T) {
+ tests := []struct {
+ name string
+ sa *SockaddrUnix
+ raw *RawSockaddrUnix
+ slen _Socklen
+ err error
+ }{
+ {
+ name: "unnamed",
+ sa: &SockaddrUnix{},
+ raw: &RawSockaddrUnix{
+ Family: AF_UNIX,
+ },
+ slen: 2, // family (uint16)
+ },
+ {
+ name: "abstract",
+ sa: &SockaddrUnix{
+ Name: "@",
+ },
+ raw: &RawSockaddrUnix{
+ Family: AF_UNIX,
+ },
+ slen: 3, // family (uint16) + NULL
+ },
+ {
+ name: "named",
+ sa: &SockaddrUnix{
+ Name: "gopher",
+ },
+ raw: &RawSockaddrUnix{
+ Family: AF_UNIX,
+ Path: [108]int8{'g', 'o', 'p', 'h', 'e', 'r'},
+ },
+ slen: _Socklen(3 + len("gopher")), // family (uint16) + len(gopher)
+ },
+ {
+ name: "named too long",
+ sa: &SockaddrUnix{
+ Name: strings.Repeat("A", 108),
+ },
+ err: EINVAL,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ out, l, err := tt.sa.sockaddr()
+ if err != tt.err {
+ t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
+ }
+
+ if l != tt.slen {
+ t.Fatalf("unexpected Socklen: %d, want %d", l, tt.slen)
+ }
+ if out == nil {
+ // No pointer to cast, return early.
+ return
+ }
+
+ raw := (*RawSockaddrUnix)(out)
+ if !reflect.DeepEqual(raw, tt.raw) {
+ t.Fatalf("unexpected RawSockaddrUnix:\n got: %#v\nwant: %#v", raw, tt.raw)
+ }
+ })
+ }
+
+}
+
// These helpers explicitly copy the contents of in into out to produce
// the correct sockaddr structure, without relying on unsafe casting to
// a type of a larger size.
@@ -402,3 +492,17 @@
)
return &out
}
+
+func sockaddrUnixToAny(in RawSockaddrUnix) *RawSockaddrAny {
+ var out RawSockaddrAny
+
+ // Explicitly copy the contents of in into out to produce the correct
+ // sockaddr structure, without relying on unsafe casting to a type of a
+ // larger size.
+ copy(
+ (*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
+ (*(*[SizeofSockaddrUnix]byte)(unsafe.Pointer(&in)))[:],
+ )
+
+ return &out
+}