diff options
Diffstat (limited to 'src/net/unixsock_readmsg_test.go')
-rw-r--r-- | src/net/unixsock_readmsg_test.go | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/net/unixsock_readmsg_test.go b/src/net/unixsock_readmsg_test.go new file mode 100644 index 0000000..414f626 --- /dev/null +++ b/src/net/unixsock_readmsg_test.go @@ -0,0 +1,104 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build unix + +package net + +import ( + "os" + "syscall" + "testing" + "time" +) + +func TestUnixConnReadMsgUnixSCMRightsCloseOnExec(t *testing.T) { + if !testableNetwork("unix") { + t.Skip("not unix system") + } + + scmFile, err := os.Open(os.DevNull) + if err != nil { + t.Fatalf("file open: %v", err) + } + defer scmFile.Close() + + rights := syscall.UnixRights(int(scmFile.Fd())) + fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0) + if err != nil { + t.Fatalf("Socketpair: %v", err) + } + + writeFile := os.NewFile(uintptr(fds[0]), "write-socket") + defer writeFile.Close() + readFile := os.NewFile(uintptr(fds[1]), "read-socket") + defer readFile.Close() + + cw, err := FileConn(writeFile) + if err != nil { + t.Fatalf("FileConn: %v", err) + } + defer cw.Close() + cr, err := FileConn(readFile) + if err != nil { + t.Fatalf("FileConn: %v", err) + } + defer cr.Close() + + ucw, ok := cw.(*UnixConn) + if !ok { + t.Fatalf("got %T; want UnixConn", cw) + } + ucr, ok := cr.(*UnixConn) + if !ok { + t.Fatalf("got %T; want UnixConn", cr) + } + + oob := make([]byte, syscall.CmsgSpace(4)) + err = ucw.SetWriteDeadline(time.Now().Add(5 * time.Second)) + if err != nil { + t.Fatalf("Can't set unix connection timeout: %v", err) + } + _, _, err = ucw.WriteMsgUnix(nil, rights, nil) + if err != nil { + t.Fatalf("UnixConn readMsg: %v", err) + } + err = ucr.SetReadDeadline(time.Now().Add(5 * time.Second)) + if err != nil { + t.Fatalf("Can't set unix connection timeout: %v", err) + } + _, oobn, _, _, err := ucr.ReadMsgUnix(nil, oob) + if err != nil { + t.Fatalf("UnixConn readMsg: %v", err) + } + + scms, err := syscall.ParseSocketControlMessage(oob[:oobn]) + if err != nil { + t.Fatalf("ParseSocketControlMessage: %v", err) + } + if len(scms) != 1 { + t.Fatalf("got scms = %#v; expected 1 SocketControlMessage", scms) + } + scm := scms[0] + gotFDs, err := syscall.ParseUnixRights(&scm) + if err != nil { + t.Fatalf("syscall.ParseUnixRights: %v", err) + } + if len(gotFDs) != 1 { + t.Fatalf("got FDs %#v: wanted only 1 fd", gotFDs) + } + defer func() { + if err := syscall.Close(gotFDs[0]); err != nil { + t.Fatalf("fail to close gotFDs: %v", err) + } + }() + + flags, err := fcntl(gotFDs[0], syscall.F_GETFD, 0) + if err != nil { + t.Fatalf("Can't get flags of fd:%#v, with err:%v", gotFDs[0], err) + } + if flags&syscall.FD_CLOEXEC == 0 { + t.Fatalf("got flags %#x, want %#x (FD_CLOEXEC) set", flags, syscall.FD_CLOEXEC) + } +} |