github.com/AESNooper/go/src@v0.0.0-20220218095104-b56a4ab1bbbb/os/fifo_test.go (about)

     1  // Copyright 2015 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 darwin || dragonfly || freebsd || linux || netbsd || openbsd
     6  
     7  package os_test
     8  
     9  import (
    10  	"bufio"
    11  	"bytes"
    12  	"fmt"
    13  	"io"
    14  	"os"
    15  	"path/filepath"
    16  	"runtime"
    17  	"sync"
    18  	"syscall"
    19  	"testing"
    20  	"time"
    21  )
    22  
    23  // Issue 24164.
    24  func TestFifoEOF(t *testing.T) {
    25  	switch runtime.GOOS {
    26  	case "android":
    27  		t.Skip("skipping on Android; mkfifo syscall not available")
    28  	}
    29  
    30  	dir := t.TempDir()
    31  	fifoName := filepath.Join(dir, "fifo")
    32  	if err := syscall.Mkfifo(fifoName, 0600); err != nil {
    33  		t.Fatal(err)
    34  	}
    35  
    36  	var wg sync.WaitGroup
    37  	wg.Add(1)
    38  	go func() {
    39  		defer wg.Done()
    40  
    41  		w, err := os.OpenFile(fifoName, os.O_WRONLY, 0)
    42  		if err != nil {
    43  			t.Error(err)
    44  			return
    45  		}
    46  
    47  		defer func() {
    48  			if err := w.Close(); err != nil {
    49  				t.Errorf("error closing writer: %v", err)
    50  			}
    51  		}()
    52  
    53  		for i := 0; i < 3; i++ {
    54  			time.Sleep(10 * time.Millisecond)
    55  			_, err := fmt.Fprintf(w, "line %d\n", i)
    56  			if err != nil {
    57  				t.Errorf("error writing to fifo: %v", err)
    58  				return
    59  			}
    60  		}
    61  		time.Sleep(10 * time.Millisecond)
    62  	}()
    63  
    64  	defer wg.Wait()
    65  
    66  	r, err := os.Open(fifoName)
    67  	if err != nil {
    68  		t.Fatal(err)
    69  	}
    70  
    71  	done := make(chan bool)
    72  	go func() {
    73  		defer close(done)
    74  
    75  		defer func() {
    76  			if err := r.Close(); err != nil {
    77  				t.Errorf("error closing reader: %v", err)
    78  			}
    79  		}()
    80  
    81  		rbuf := bufio.NewReader(r)
    82  		for {
    83  			b, err := rbuf.ReadBytes('\n')
    84  			if err == io.EOF {
    85  				break
    86  			}
    87  			if err != nil {
    88  				t.Error(err)
    89  				return
    90  			}
    91  			t.Logf("%s\n", bytes.TrimSpace(b))
    92  		}
    93  	}()
    94  
    95  	select {
    96  	case <-done:
    97  		// Test succeeded.
    98  	case <-time.After(time.Second):
    99  		t.Error("timed out waiting for read")
   100  		// Close the reader to force the read to complete.
   101  		r.Close()
   102  	}
   103  }