aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/net/unixsock_readmsg_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/net/unixsock_readmsg_test.go')
-rw-r--r--libgo/go/net/unixsock_readmsg_test.go105
1 files changed, 105 insertions, 0 deletions
diff --git a/libgo/go/net/unixsock_readmsg_test.go b/libgo/go/net/unixsock_readmsg_test.go
new file mode 100644
index 0000000..a4d2fca
--- /dev/null
+++ b/libgo/go/net/unixsock_readmsg_test.go
@@ -0,0 +1,105 @@
+// 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 aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+
+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)
+ }
+}