golang.org/x/sys@v0.20.1-0.20240517151509-673e0f94c16d/unix/pipe2_test.go (about) 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 5 //go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris 6 7 package unix_test 8 9 import ( 10 "testing" 11 12 "golang.org/x/sys/unix" 13 ) 14 15 func TestPipe2(t *testing.T) { 16 const s = "hello" 17 var pipes [2]int 18 err := unix.Pipe2(pipes[:], 0) 19 if err != nil { 20 t.Fatalf("pipe2: %v", err) 21 } 22 r := pipes[0] 23 w := pipes[1] 24 go func() { 25 n, err := unix.Write(w, []byte(s)) 26 if err != nil { 27 t.Errorf("bad write: %v", err) 28 return 29 } 30 if n != len(s) { 31 t.Errorf("bad write count: %d", n) 32 return 33 } 34 err = unix.Close(w) 35 if err != nil { 36 t.Errorf("bad close: %v", err) 37 return 38 } 39 }() 40 var buf [10 + len(s)]byte 41 n, err := unix.Read(r, buf[:]) 42 if err != nil { 43 t.Fatalf("bad read: %v", err) 44 } 45 if n != len(s) { 46 t.Fatalf("bad read count: %d", n) 47 } 48 if string(buf[:n]) != s { 49 t.Fatalf("bad contents: %s", string(buf[:n])) 50 } 51 err = unix.Close(r) 52 if err != nil { 53 t.Fatalf("bad close: %v", err) 54 } 55 } 56 57 func checkNonblocking(t *testing.T, fd int, name string) { 58 t.Helper() 59 flags, err := unix.FcntlInt(uintptr(fd), unix.F_GETFL, 0) 60 if err != nil { 61 t.Errorf("fcntl(%s, F_GETFL) failed: %v", name, err) 62 } else if flags&unix.O_NONBLOCK == 0 { 63 t.Errorf("O_NONBLOCK not set in %s flags %#x", name, flags) 64 } 65 } 66 67 func checkCloseonexec(t *testing.T, fd int, name string) { 68 t.Helper() 69 flags, err := unix.FcntlInt(uintptr(fd), unix.F_GETFD, 0) 70 if err != nil { 71 t.Errorf("fcntl(%s, F_GETFD) failed: %v", name, err) 72 } else if flags&unix.FD_CLOEXEC == 0 { 73 t.Errorf("FD_CLOEXEC not set in %s flags %#x", name, flags) 74 } 75 } 76 77 func TestNonblockingPipe2(t *testing.T) { 78 var pipes [2]int 79 err := unix.Pipe2(pipes[:], unix.O_NONBLOCK|unix.O_CLOEXEC) 80 if err != nil { 81 t.Fatalf("pipe2: %v", err) 82 } 83 r := pipes[0] 84 w := pipes[1] 85 defer func() { 86 unix.Close(r) 87 unix.Close(w) 88 }() 89 90 checkNonblocking(t, r, "reader") 91 checkCloseonexec(t, r, "reader") 92 checkNonblocking(t, w, "writer") 93 checkCloseonexec(t, w, "writer") 94 }