github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/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  // +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  	case "openbsd":
    29  		// On OpenBSD 6.2 this test just hangs for some reason.
    30  		t.Skip("skipping on OpenBSD; issue 25877")
    31  	}
    32  
    33  	dir, err := os.MkdirTemp("", "TestFifoEOF")
    34  	if err != nil {
    35  		t.Fatal(err)
    36  	}
    37  	defer os.RemoveAll(dir)
    38  
    39  	fifoName := filepath.Join(dir, "fifo")
    40  	if err := syscall.Mkfifo(fifoName, 0600); err != nil {
    41  		t.Fatal(err)
    42  	}
    43  
    44  	var wg sync.WaitGroup
    45  	wg.Add(1)
    46  	go func() {
    47  		defer wg.Done()
    48  
    49  		w, err := os.OpenFile(fifoName, os.O_WRONLY, 0)
    50  		if err != nil {
    51  			t.Error(err)
    52  			return
    53  		}
    54  
    55  		defer func() {
    56  			if err := w.Close(); err != nil {
    57  				t.Errorf("error closing writer: %v", err)
    58  			}
    59  		}()
    60  
    61  		for i := 0; i < 3; i++ {
    62  			time.Sleep(10 * time.Millisecond)
    63  			_, err := fmt.Fprintf(w, "line %d\n", i)
    64  			if err != nil {
    65  				t.Errorf("error writing to fifo: %v", err)
    66  				return
    67  			}
    68  		}
    69  		time.Sleep(10 * time.Millisecond)
    70  	}()
    71  
    72  	defer wg.Wait()
    73  
    74  	r, err := os.Open(fifoName)
    75  	if err != nil {
    76  		t.Fatal(err)
    77  	}
    78  
    79  	done := make(chan bool)
    80  	go func() {
    81  		defer close(done)
    82  
    83  		defer func() {
    84  			if err := r.Close(); err != nil {
    85  				t.Errorf("error closing reader: %v", err)
    86  			}
    87  		}()
    88  
    89  		rbuf := bufio.NewReader(r)
    90  		for {
    91  			b, err := rbuf.ReadBytes('\n')
    92  			if err == io.EOF {
    93  				break
    94  			}
    95  			if err != nil {
    96  				t.Error(err)
    97  				return
    98  			}
    99  			t.Logf("%s\n", bytes.TrimSpace(b))
   100  		}
   101  	}()
   102  
   103  	select {
   104  	case <-done:
   105  		// Test succeeded.
   106  	case <-time.After(time.Second):
   107  		t.Error("timed out waiting for read")
   108  		// Close the reader to force the read to complete.
   109  		r.Close()
   110  	}
   111  }