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 }