github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/nbpipe_test.go (about) 1 // Copyright 2019 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 unix 6 7 package runtime_test 8 9 import ( 10 "runtime" 11 "syscall" 12 "testing" 13 "unsafe" 14 ) 15 16 func TestNonblockingPipe(t *testing.T) { 17 t.Parallel() 18 19 // NonblockingPipe is the test name for nonblockingPipe. 20 r, w, errno := runtime.NonblockingPipe() 21 if errno != 0 { 22 t.Fatal(syscall.Errno(errno)) 23 } 24 defer func() { 25 runtime.Close(r) 26 runtime.Close(w) 27 }() 28 29 checkIsPipe(t, r, w) 30 checkNonblocking(t, r, "reader") 31 checkCloseonexec(t, r, "reader") 32 checkNonblocking(t, w, "writer") 33 checkCloseonexec(t, w, "writer") 34 } 35 36 func checkIsPipe(t *testing.T, r, w int32) { 37 bw := byte(42) 38 if n := runtime.Write(uintptr(w), unsafe.Pointer(&bw), 1); n != 1 { 39 t.Fatalf("Write(w, &b, 1) == %d, expected 1", n) 40 } 41 var br byte 42 if n := runtime.Read(r, unsafe.Pointer(&br), 1); n != 1 { 43 t.Fatalf("Read(r, &b, 1) == %d, expected 1", n) 44 } 45 if br != bw { 46 t.Errorf("pipe read %d, expected %d", br, bw) 47 } 48 } 49 50 func checkNonblocking(t *testing.T, fd int32, name string) { 51 t.Helper() 52 flags, errno := fcntl(uintptr(fd), syscall.F_GETFL, 0) 53 if errno != 0 { 54 t.Errorf("fcntl(%s, F_GETFL) failed: %v", name, syscall.Errno(errno)) 55 } else if flags&syscall.O_NONBLOCK == 0 { 56 t.Errorf("O_NONBLOCK not set in %s flags %#x", name, flags) 57 } 58 } 59 60 func checkCloseonexec(t *testing.T, fd int32, name string) { 61 t.Helper() 62 flags, errno := fcntl(uintptr(fd), syscall.F_GETFD, 0) 63 if errno != 0 { 64 t.Errorf("fcntl(%s, F_GETFD) failed: %v", name, syscall.Errno(errno)) 65 } else if flags&syscall.FD_CLOEXEC == 0 { 66 t.Errorf("FD_CLOEXEC not set in %s flags %#x", name, flags) 67 } 68 }