golang.org/x/sys@v0.20.1-0.20240517151509-673e0f94c16d/unix/pipe2_test.go (about)

     1  // Copyright 2021 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 dragonfly || freebsd || linux || netbsd || openbsd || solaris
     6  
     7  package unix_test
     8  
     9  import (
    10  	"testing"
    11  
    12  	"golang.org/x/sys/unix"
    13  )
    14  
    15  func TestPipe2(t *testing.T) {
    16  	const s = "hello"
    17  	var pipes [2]int
    18  	err := unix.Pipe2(pipes[:], 0)
    19  	if err != nil {
    20  		t.Fatalf("pipe2: %v", err)
    21  	}
    22  	r := pipes[0]
    23  	w := pipes[1]
    24  	go func() {
    25  		n, err := unix.Write(w, []byte(s))
    26  		if err != nil {
    27  			t.Errorf("bad write: %v", err)
    28  			return
    29  		}
    30  		if n != len(s) {
    31  			t.Errorf("bad write count: %d", n)
    32  			return
    33  		}
    34  		err = unix.Close(w)
    35  		if err != nil {
    36  			t.Errorf("bad close: %v", err)
    37  			return
    38  		}
    39  	}()
    40  	var buf [10 + len(s)]byte
    41  	n, err := unix.Read(r, buf[:])
    42  	if err != nil {
    43  		t.Fatalf("bad read: %v", err)
    44  	}
    45  	if n != len(s) {
    46  		t.Fatalf("bad read count: %d", n)
    47  	}
    48  	if string(buf[:n]) != s {
    49  		t.Fatalf("bad contents: %s", string(buf[:n]))
    50  	}
    51  	err = unix.Close(r)
    52  	if err != nil {
    53  		t.Fatalf("bad close: %v", err)
    54  	}
    55  }
    56  
    57  func checkNonblocking(t *testing.T, fd int, name string) {
    58  	t.Helper()
    59  	flags, err := unix.FcntlInt(uintptr(fd), unix.F_GETFL, 0)
    60  	if err != nil {
    61  		t.Errorf("fcntl(%s, F_GETFL) failed: %v", name, err)
    62  	} else if flags&unix.O_NONBLOCK == 0 {
    63  		t.Errorf("O_NONBLOCK not set in %s flags %#x", name, flags)
    64  	}
    65  }
    66  
    67  func checkCloseonexec(t *testing.T, fd int, name string) {
    68  	t.Helper()
    69  	flags, err := unix.FcntlInt(uintptr(fd), unix.F_GETFD, 0)
    70  	if err != nil {
    71  		t.Errorf("fcntl(%s, F_GETFD) failed: %v", name, err)
    72  	} else if flags&unix.FD_CLOEXEC == 0 {
    73  		t.Errorf("FD_CLOEXEC not set in %s flags %#x", name, flags)
    74  	}
    75  }
    76  
    77  func TestNonblockingPipe2(t *testing.T) {
    78  	var pipes [2]int
    79  	err := unix.Pipe2(pipes[:], unix.O_NONBLOCK|unix.O_CLOEXEC)
    80  	if err != nil {
    81  		t.Fatalf("pipe2: %v", err)
    82  	}
    83  	r := pipes[0]
    84  	w := pipes[1]
    85  	defer func() {
    86  		unix.Close(r)
    87  		unix.Close(w)
    88  	}()
    89  
    90  	checkNonblocking(t, r, "reader")
    91  	checkCloseonexec(t, r, "reader")
    92  	checkNonblocking(t, w, "writer")
    93  	checkCloseonexec(t, w, "writer")
    94  }