...

Source file src/runtime/nbpipe_test.go

Documentation: runtime

		 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 aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
		 6  // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
		 7  
		 8  package runtime_test
		 9  
		10  import (
		11  	"runtime"
		12  	"syscall"
		13  	"testing"
		14  	"unsafe"
		15  )
		16  
		17  func TestNonblockingPipe(t *testing.T) {
		18  	t.Parallel()
		19  
		20  	// NonblockingPipe is the test name for nonblockingPipe.
		21  	r, w, errno := runtime.NonblockingPipe()
		22  	if errno != 0 {
		23  		t.Fatal(syscall.Errno(errno))
		24  	}
		25  	defer func() {
		26  		runtime.Close(r)
		27  		runtime.Close(w)
		28  	}()
		29  
		30  	checkIsPipe(t, r, w)
		31  	checkNonblocking(t, r, "reader")
		32  	checkCloseonexec(t, r, "reader")
		33  	checkNonblocking(t, w, "writer")
		34  	checkCloseonexec(t, w, "writer")
		35  }
		36  
		37  func checkIsPipe(t *testing.T, r, w int32) {
		38  	bw := byte(42)
		39  	if n := runtime.Write(uintptr(w), unsafe.Pointer(&bw), 1); n != 1 {
		40  		t.Fatalf("Write(w, &b, 1) == %d, expected 1", n)
		41  	}
		42  	var br byte
		43  	if n := runtime.Read(r, unsafe.Pointer(&br), 1); n != 1 {
		44  		t.Fatalf("Read(r, &b, 1) == %d, expected 1", n)
		45  	}
		46  	if br != bw {
		47  		t.Errorf("pipe read %d, expected %d", br, bw)
		48  	}
		49  }
		50  
		51  func checkNonblocking(t *testing.T, fd int32, name string) {
		52  	t.Helper()
		53  	flags, errno := fcntl(uintptr(fd), syscall.F_GETFL, 0)
		54  	if errno != 0 {
		55  		t.Errorf("fcntl(%s, F_GETFL) failed: %v", name, syscall.Errno(errno))
		56  	} else if flags&syscall.O_NONBLOCK == 0 {
		57  		t.Errorf("O_NONBLOCK not set in %s flags %#x", name, flags)
		58  	}
		59  }
		60  
		61  func checkCloseonexec(t *testing.T, fd int32, name string) {
		62  	t.Helper()
		63  	flags, errno := fcntl(uintptr(fd), syscall.F_GETFD, 0)
		64  	if errno != 0 {
		65  		t.Errorf("fcntl(%s, F_GETFD) failed: %v", name, syscall.Errno(errno))
		66  	} else if flags&syscall.FD_CLOEXEC == 0 {
		67  		t.Errorf("FD_CLOEXEC not set in %s flags %#x", name, flags)
		68  	}
		69  }
		70  
		71  func TestSetNonblock(t *testing.T) {
		72  	t.Parallel()
		73  
		74  	r, w, errno := runtime.Pipe()
		75  	if errno != 0 {
		76  		t.Fatal(syscall.Errno(errno))
		77  	}
		78  	defer func() {
		79  		runtime.Close(r)
		80  		runtime.Close(w)
		81  	}()
		82  
		83  	checkIsPipe(t, r, w)
		84  
		85  	runtime.SetNonblock(r)
		86  	runtime.SetNonblock(w)
		87  	checkNonblocking(t, r, "reader")
		88  	checkNonblocking(t, w, "writer")
		89  
		90  	runtime.Closeonexec(r)
		91  	runtime.Closeonexec(w)
		92  	checkCloseonexec(t, r, "reader")
		93  	checkCloseonexec(t, w, "writer")
		94  }
		95  

View as plain text