unixsock_readmsg_test.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright 2021 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
  5. package net
  6. import (
  7. "os"
  8. "syscall"
  9. "testing"
  10. "time"
  11. )
  12. func TestUnixConnReadMsgUnixSCMRightsCloseOnExec(t *testing.T) {
  13. if !testableNetwork("unix") {
  14. t.Skip("not unix system")
  15. }
  16. scmFile, err := os.Open(os.DevNull)
  17. if err != nil {
  18. t.Fatalf("file open: %v", err)
  19. }
  20. defer scmFile.Close()
  21. rights := syscall.UnixRights(int(scmFile.Fd()))
  22. fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
  23. if err != nil {
  24. t.Fatalf("Socketpair: %v", err)
  25. }
  26. writeFile := os.NewFile(uintptr(fds[0]), "write-socket")
  27. defer writeFile.Close()
  28. readFile := os.NewFile(uintptr(fds[1]), "read-socket")
  29. defer readFile.Close()
  30. cw, err := FileConn(writeFile)
  31. if err != nil {
  32. t.Fatalf("FileConn: %v", err)
  33. }
  34. defer cw.Close()
  35. cr, err := FileConn(readFile)
  36. if err != nil {
  37. t.Fatalf("FileConn: %v", err)
  38. }
  39. defer cr.Close()
  40. ucw, ok := cw.(*UnixConn)
  41. if !ok {
  42. t.Fatalf("got %T; want UnixConn", cw)
  43. }
  44. ucr, ok := cr.(*UnixConn)
  45. if !ok {
  46. t.Fatalf("got %T; want UnixConn", cr)
  47. }
  48. oob := make([]byte, syscall.CmsgSpace(4))
  49. err = ucw.SetWriteDeadline(time.Now().Add(5 * time.Second))
  50. if err != nil {
  51. t.Fatalf("Can't set unix connection timeout: %v", err)
  52. }
  53. _, _, err = ucw.WriteMsgUnix(nil, rights, nil)
  54. if err != nil {
  55. t.Fatalf("UnixConn readMsg: %v", err)
  56. }
  57. err = ucr.SetReadDeadline(time.Now().Add(5 * time.Second))
  58. if err != nil {
  59. t.Fatalf("Can't set unix connection timeout: %v", err)
  60. }
  61. _, oobn, _, _, err := ucr.ReadMsgUnix(nil, oob)
  62. if err != nil {
  63. t.Fatalf("UnixConn readMsg: %v", err)
  64. }
  65. scms, err := syscall.ParseSocketControlMessage(oob[:oobn])
  66. if err != nil {
  67. t.Fatalf("ParseSocketControlMessage: %v", err)
  68. }
  69. if len(scms) != 1 {
  70. t.Fatalf("got scms = %#v; expected 1 SocketControlMessage", scms)
  71. }
  72. scm := scms[0]
  73. gotFDs, err := syscall.ParseUnixRights(&scm)
  74. if err != nil {
  75. t.Fatalf("syscall.ParseUnixRights: %v", err)
  76. }
  77. if len(gotFDs) != 1 {
  78. t.Fatalf("got FDs %#v: wanted only 1 fd", gotFDs)
  79. }
  80. defer func() {
  81. if err := syscall.Close(gotFDs[0]); err != nil {
  82. t.Fatalf("fail to close gotFDs: %v", err)
  83. }
  84. }()
  85. flags, err := fcntl(gotFDs[0], syscall.F_GETFD, 0)
  86. if err != nil {
  87. t.Fatalf("Can't get flags of fd:%#v, with err:%v", gotFDs[0], err)
  88. }
  89. if flags&syscall.FD_CLOEXEC == 0 {
  90. t.Fatalf("got flags %#x, want %#x (FD_CLOEXEC) set", flags, syscall.FD_CLOEXEC)
  91. }
  92. }