blob: 2f0e06bc52a626f115d4dfff9726a4501a6c5a56 [file] [log] [blame]
// 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.
//go:build darwin || dragonfly || freebsd || (linux && !android) || netbsd || openbsd
package os_test
import (
"os"
"path/filepath"
"syscall"
"testing"
)
func TestFifoEOF(t *testing.T) {
t.Parallel()
dir := t.TempDir()
fifoName := filepath.Join(dir, "fifo")
if err := syscall.Mkfifo(fifoName, 0600); err != nil {
t.Fatal(err)
}
// Per https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html#tag_16_357_03:
//
// - “If O_NONBLOCK is clear, an open() for reading-only shall block the
// calling thread until a thread opens the file for writing. An open() for
// writing-only shall block the calling thread until a thread opens the file
// for reading.”
//
// In order to unblock both open calls, we open the two ends of the FIFO
// simultaneously in separate goroutines.
rc := make(chan *os.File, 1)
go func() {
r, err := os.Open(fifoName)
if err != nil {
t.Error(err)
}
rc <- r
}()
w, err := os.OpenFile(fifoName, os.O_WRONLY, 0)
if err != nil {
t.Error(err)
}
r := <-rc
if t.Failed() {
if r != nil {
r.Close()
}
if w != nil {
w.Close()
}
return
}
testPipeEOF(t, r, w)
}