mirror of
https://github.com/golang/go
synced 2024-11-06 13:46:16 -07:00
a2baae6851
For #20322 For #51572 Change-Id: Id0b4799d097d01128e98ba4cc0092298357bca45 Reviewed-on: https://go-review.googlesource.com/c/go/+/389935 Trust: Ian Lance Taylor <iant@golang.org> Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
69 lines
1.7 KiB
Go
69 lines
1.7 KiB
Go
// 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)
|
|
}
|
|
}
|