Source file
src/net/unixsock_readmsg_test.go
1
2
3
4
5
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 }
105
View as plain text