2019-04-03 17:31:13 -06:00
|
|
|
// 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.
|
|
|
|
|
2022-03-03 19:23:35 -07:00
|
|
|
//go:build unix
|
2019-04-03 17:31:13 -06:00
|
|
|
|
|
|
|
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()
|
2019-10-29 08:39:42 -06:00
|
|
|
flags, errno := fcntl(uintptr(fd), syscall.F_GETFL, 0)
|
2019-04-03 17:31:13 -06:00
|
|
|
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()
|
2019-10-29 08:39:42 -06:00
|
|
|
flags, errno := fcntl(uintptr(fd), syscall.F_GETFD, 0)
|
2019-04-03 17:31:13 -06:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|