123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- // 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)
- }
- }
|