golang.org/x/sys@v0.20.1-0.20240517151509-673e0f94c16d/unix/syscall_internal_bsd_test.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build darwin || dragonfly || freebsd || netbsd || openbsd 6 7 package unix 8 9 import ( 10 "reflect" 11 "strings" 12 "testing" 13 "unsafe" 14 ) 15 16 func Test_anyToSockaddr(t *testing.T) { 17 tests := []struct { 18 name string 19 rsa *RawSockaddrAny 20 sa Sockaddr 21 err error 22 }{ 23 { 24 name: "AF_UNIX zero length", 25 rsa: sockaddrUnixToAny(RawSockaddrUnix{ 26 Family: AF_UNIX, 27 }), 28 err: EINVAL, 29 }, 30 { 31 name: "AF_UNIX unnamed", 32 rsa: sockaddrUnixToAny(RawSockaddrUnix{ 33 Len: 2, // family (uint16) 34 Family: AF_UNIX, 35 }), 36 sa: &SockaddrUnix{}, 37 }, 38 { 39 name: "AF_UNIX named", 40 rsa: sockaddrUnixToAny(RawSockaddrUnix{ 41 Len: uint8(2 + len("gopher")), // family (uint16) + len(gopher) 42 Family: AF_UNIX, 43 Path: [104]int8{'g', 'o', 'p', 'h', 'e', 'r'}, 44 }), 45 sa: &SockaddrUnix{ 46 Name: "gopher", 47 }, 48 }, 49 { 50 name: "AF_UNIX named", 51 rsa: sockaddrUnixToAny(RawSockaddrUnix{ 52 Len: uint8(2 + len("go")), 53 Family: AF_UNIX, 54 Path: [104]int8{'g', 'o', 'p', 'h', 'e', 'r'}, 55 }), 56 sa: &SockaddrUnix{ 57 Name: "go", 58 }, 59 }, 60 { 61 name: "AF_MAX EAFNOSUPPORT", 62 rsa: &RawSockaddrAny{ 63 Addr: RawSockaddr{ 64 Family: AF_MAX, 65 }, 66 }, 67 err: EAFNOSUPPORT, 68 }, 69 // TODO: expand to support other families. 70 } 71 72 for _, tt := range tests { 73 t.Run(tt.name, func(t *testing.T) { 74 fd := int(0) 75 sa, err := anyToSockaddr(fd, tt.rsa) 76 if err != tt.err { 77 t.Fatalf("unexpected error: %v, want: %v", err, tt.err) 78 } 79 80 if !reflect.DeepEqual(sa, tt.sa) { 81 t.Fatalf("unexpected Sockaddr:\n got: %#v\nwant: %#v", sa, tt.sa) 82 } 83 }) 84 } 85 } 86 87 func TestSockaddrUnix_sockaddr(t *testing.T) { 88 tests := []struct { 89 name string 90 sa *SockaddrUnix 91 raw *RawSockaddrUnix 92 err error 93 }{ 94 { 95 name: "unnamed", 96 sa: &SockaddrUnix{}, 97 raw: &RawSockaddrUnix{ 98 Family: AF_UNIX, 99 }, 100 err: EINVAL, 101 }, 102 { 103 name: "named", 104 sa: &SockaddrUnix{ 105 Name: "gopher", 106 }, 107 raw: &RawSockaddrUnix{ 108 Len: uint8(2 + len("gopher") + 1), // family (uint16) + len(gopher) + '\0' 109 Family: AF_UNIX, 110 Path: [104]int8{'g', 'o', 'p', 'h', 'e', 'r'}, 111 }, 112 }, 113 { 114 name: "named too long", 115 sa: &SockaddrUnix{ 116 Name: strings.Repeat("A", 104), 117 }, 118 err: EINVAL, 119 }, 120 } 121 122 for _, tt := range tests { 123 t.Run(tt.name, func(t *testing.T) { 124 out, _, err := tt.sa.sockaddr() 125 if err != tt.err { 126 t.Fatalf("unexpected error: %v, want: %v", err, tt.err) 127 } 128 129 if out == nil { 130 // No pointer to cast, return early. 131 return 132 } 133 134 raw := (*RawSockaddrUnix)(out) 135 if !reflect.DeepEqual(raw, tt.raw) { 136 t.Fatalf("unexpected RawSockaddrUnix:\n got: %#v\nwant: %#v", raw, tt.raw) 137 } 138 }) 139 } 140 } 141 142 func sockaddrUnixToAny(in RawSockaddrUnix) *RawSockaddrAny { 143 var out RawSockaddrAny 144 145 // Explicitly copy the contents of in into out to produce the correct 146 // sockaddr structure, without relying on unsafe casting to a type of a 147 // larger size. 148 copy( 149 (*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:], 150 (*(*[SizeofSockaddrUnix]byte)(unsafe.Pointer(&in)))[:], 151 ) 152 153 return &out 154 }