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  }