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