105 lines
2.5 KiB
Go
105 lines
2.5 KiB
Go
// 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
|
|
|
|
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)
|
|
}
|
|
}
|