diff options
Diffstat (limited to 'src/os/fifo_test.go')
-rw-r--r-- | src/os/fifo_test.go | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/os/fifo_test.go b/src/os/fifo_test.go new file mode 100644 index 0000000..2439192 --- /dev/null +++ b/src/os/fifo_test.go @@ -0,0 +1,111 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux netbsd openbsd + +package os_test + +import ( + "bufio" + "bytes" + "fmt" + "io" + "os" + "path/filepath" + "runtime" + "sync" + "syscall" + "testing" + "time" +) + +// Issue 24164. +func TestFifoEOF(t *testing.T) { + switch runtime.GOOS { + case "android": + t.Skip("skipping on Android; mkfifo syscall not available") + case "openbsd": + // On OpenBSD 6.2 this test just hangs for some reason. + t.Skip("skipping on OpenBSD; issue 25877") + } + + dir, err := os.MkdirTemp("", "TestFifoEOF") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + fifoName := filepath.Join(dir, "fifo") + if err := syscall.Mkfifo(fifoName, 0600); err != nil { + t.Fatal(err) + } + + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + + w, err := os.OpenFile(fifoName, os.O_WRONLY, 0) + if err != nil { + t.Error(err) + return + } + + defer func() { + if err := w.Close(); err != nil { + t.Errorf("error closing writer: %v", err) + } + }() + + for i := 0; i < 3; i++ { + time.Sleep(10 * time.Millisecond) + _, err := fmt.Fprintf(w, "line %d\n", i) + if err != nil { + t.Errorf("error writing to fifo: %v", err) + return + } + } + time.Sleep(10 * time.Millisecond) + }() + + defer wg.Wait() + + r, err := os.Open(fifoName) + if err != nil { + t.Fatal(err) + } + + done := make(chan bool) + go func() { + defer close(done) + + defer func() { + if err := r.Close(); err != nil { + t.Errorf("error closing reader: %v", err) + } + }() + + rbuf := bufio.NewReader(r) + for { + b, err := rbuf.ReadBytes('\n') + if err == io.EOF { + break + } + if err != nil { + t.Error(err) + return + } + t.Logf("%s\n", bytes.TrimSpace(b)) + } + }() + + select { + case <-done: + // Test succeeded. + case <-time.After(time.Second): + t.Error("timed out waiting for read") + // Close the reader to force the read to complete. + r.Close() + } +} |