github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/net/unixsock_readmsg_test.go (about) 1 // Copyright 2021 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 unix 6 7 package net 8 9 import ( 10 "os" 11 "syscall" 12 "testing" 13 "time" 14 ) 15 16 func TestUnixConnReadMsgUnixSCMRightsCloseOnExec(t *testing.T) { 17 if !testableNetwork("unix") { 18 t.Skip("not unix system") 19 } 20 21 scmFile, err := os.Open(os.DevNull) 22 if err != nil { 23 t.Fatalf("file open: %v", err) 24 } 25 defer scmFile.Close() 26 27 rights := syscall.UnixRights(int(scmFile.Fd())) 28 fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0) 29 if err != nil { 30 t.Fatalf("Socketpair: %v", err) 31 } 32 33 writeFile := os.NewFile(uintptr(fds[0]), "write-socket") 34 defer writeFile.Close() 35 readFile := os.NewFile(uintptr(fds[1]), "read-socket") 36 defer readFile.Close() 37 38 cw, err := FileConn(writeFile) 39 if err != nil { 40 t.Fatalf("FileConn: %v", err) 41 } 42 defer cw.Close() 43 cr, err := FileConn(readFile) 44 if err != nil { 45 t.Fatalf("FileConn: %v", err) 46 } 47 defer cr.Close() 48 49 ucw, ok := cw.(*UnixConn) 50 if !ok { 51 t.Fatalf("got %T; want UnixConn", cw) 52 } 53 ucr, ok := cr.(*UnixConn) 54 if !ok { 55 t.Fatalf("got %T; want UnixConn", cr) 56 } 57 58 oob := make([]byte, syscall.CmsgSpace(4)) 59 err = ucw.SetWriteDeadline(time.Now().Add(5 * time.Second)) 60 if err != nil { 61 t.Fatalf("Can't set unix connection timeout: %v", err) 62 } 63 _, _, err = ucw.WriteMsgUnix(nil, rights, nil) 64 if err != nil { 65 t.Fatalf("UnixConn readMsg: %v", err) 66 } 67 err = ucr.SetReadDeadline(time.Now().Add(5 * time.Second)) 68 if err != nil { 69 t.Fatalf("Can't set unix connection timeout: %v", err) 70 } 71 _, oobn, _, _, err := ucr.ReadMsgUnix(nil, oob) 72 if err != nil { 73 t.Fatalf("UnixConn readMsg: %v", err) 74 } 75 76 scms, err := syscall.ParseSocketControlMessage(oob[:oobn]) 77 if err != nil { 78 t.Fatalf("ParseSocketControlMessage: %v", err) 79 } 80 if len(scms) != 1 { 81 t.Fatalf("got scms = %#v; expected 1 SocketControlMessage", scms) 82 } 83 scm := scms[0] 84 gotFDs, err := syscall.ParseUnixRights(&scm) 85 if err != nil { 86 t.Fatalf("syscall.ParseUnixRights: %v", err) 87 } 88 if len(gotFDs) != 1 { 89 t.Fatalf("got FDs %#v: wanted only 1 fd", gotFDs) 90 } 91 defer func() { 92 if err := syscall.Close(gotFDs[0]); err != nil { 93 t.Fatalf("fail to close gotFDs: %v", err) 94 } 95 }() 96 97 flags, err := fcntl(gotFDs[0], syscall.F_GETFD, 0) 98 if err != nil { 99 t.Fatalf("Can't get flags of fd:%#v, with err:%v", gotFDs[0], err) 100 } 101 if flags&syscall.FD_CLOEXEC == 0 { 102 t.Fatalf("got flags %#x, want %#x (FD_CLOEXEC) set", flags, syscall.FD_CLOEXEC) 103 } 104 }