diff options
Diffstat (limited to 'src/runtime/nbpipe_test.go')
-rw-r--r-- | src/runtime/nbpipe_test.go | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/runtime/nbpipe_test.go b/src/runtime/nbpipe_test.go new file mode 100644 index 0000000..0b0f64d --- /dev/null +++ b/src/runtime/nbpipe_test.go @@ -0,0 +1,68 @@ +// Copyright 2019 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 unix + +package runtime_test + +import ( + "runtime" + "syscall" + "testing" + "unsafe" +) + +func TestNonblockingPipe(t *testing.T) { + t.Parallel() + + // NonblockingPipe is the test name for nonblockingPipe. + r, w, errno := runtime.NonblockingPipe() + if errno != 0 { + t.Fatal(syscall.Errno(errno)) + } + defer func() { + runtime.Close(r) + runtime.Close(w) + }() + + checkIsPipe(t, r, w) + checkNonblocking(t, r, "reader") + checkCloseonexec(t, r, "reader") + checkNonblocking(t, w, "writer") + checkCloseonexec(t, w, "writer") +} + +func checkIsPipe(t *testing.T, r, w int32) { + bw := byte(42) + if n := runtime.Write(uintptr(w), unsafe.Pointer(&bw), 1); n != 1 { + t.Fatalf("Write(w, &b, 1) == %d, expected 1", n) + } + var br byte + if n := runtime.Read(r, unsafe.Pointer(&br), 1); n != 1 { + t.Fatalf("Read(r, &b, 1) == %d, expected 1", n) + } + if br != bw { + t.Errorf("pipe read %d, expected %d", br, bw) + } +} + +func checkNonblocking(t *testing.T, fd int32, name string) { + t.Helper() + flags, errno := fcntl(uintptr(fd), syscall.F_GETFL, 0) + if errno != 0 { + t.Errorf("fcntl(%s, F_GETFL) failed: %v", name, syscall.Errno(errno)) + } else if flags&syscall.O_NONBLOCK == 0 { + t.Errorf("O_NONBLOCK not set in %s flags %#x", name, flags) + } +} + +func checkCloseonexec(t *testing.T, fd int32, name string) { + t.Helper() + flags, errno := fcntl(uintptr(fd), syscall.F_GETFD, 0) + if errno != 0 { + t.Errorf("fcntl(%s, F_GETFD) failed: %v", name, syscall.Errno(errno)) + } else if flags&syscall.FD_CLOEXEC == 0 { + t.Errorf("FD_CLOEXEC not set in %s flags %#x", name, flags) + } +} |