Source file
src/runtime/nbpipe_test.go
1
2
3
4
5
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
18 r, w, errno := runtime.NonblockingPipe()
19 if errno != 0 {
20 t.Fatal(syscall.Errno(errno))
21 }
22 defer runtime.Close(w)
23
24 checkIsPipe(t, r, w)
25 checkNonblocking(t, r, "reader")
26 checkCloseonexec(t, r, "reader")
27 checkNonblocking(t, w, "writer")
28 checkCloseonexec(t, w, "writer")
29
30
31 if runtime.Close(r) != 0 {
32 t.Fatalf("Close(%d) failed", r)
33 }
34 val, errno := runtime.Fcntl(r, syscall.F_GETFD, 0)
35 if val != -1 {
36 t.Errorf("Fcntl succeeded unexpectedly")
37 } else if syscall.Errno(errno) != syscall.EBADF {
38 t.Errorf("Fcntl failed with error %v, expected %v", syscall.Errno(errno), syscall.EBADF)
39 }
40 }
41
42 func checkIsPipe(t *testing.T, r, w int32) {
43 bw := byte(42)
44 if n := runtime.Write(uintptr(w), unsafe.Pointer(&bw), 1); n != 1 {
45 t.Fatalf("Write(w, &b, 1) == %d, expected 1", n)
46 }
47 var br byte
48 if n := runtime.Read(r, unsafe.Pointer(&br), 1); n != 1 {
49 t.Fatalf("Read(r, &b, 1) == %d, expected 1", n)
50 }
51 if br != bw {
52 t.Errorf("pipe read %d, expected %d", br, bw)
53 }
54 }
55
56 func checkNonblocking(t *testing.T, fd int32, name string) {
57 t.Helper()
58 flags, errno := runtime.Fcntl(fd, syscall.F_GETFL, 0)
59 if flags == -1 {
60 t.Errorf("fcntl(%s, F_GETFL) failed: %v", name, syscall.Errno(errno))
61 } else if flags&syscall.O_NONBLOCK == 0 {
62 t.Errorf("O_NONBLOCK not set in %s flags %#x", name, flags)
63 }
64 }
65
66 func checkCloseonexec(t *testing.T, fd int32, name string) {
67 t.Helper()
68 flags, errno := runtime.Fcntl(fd, syscall.F_GETFD, 0)
69 if flags == -1 {
70 t.Errorf("fcntl(%s, F_GETFD) failed: %v", name, syscall.Errno(errno))
71 } else if flags&syscall.FD_CLOEXEC == 0 {
72 t.Errorf("FD_CLOEXEC not set in %s flags %#x", name, flags)
73 }
74 }
75
View as plain text