2018-09-17 17:15:48 +00:00
|
|
|
// +build !windows
|
|
|
|
|
|
|
|
package fifo
|
|
|
|
|
|
|
|
import (
|
2019-03-31 16:50:06 +00:00
|
|
|
"fmt"
|
2018-09-17 17:15:48 +00:00
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
|
2019-03-31 16:50:06 +00:00
|
|
|
"golang.org/x/sys/unix"
|
2018-09-17 17:15:48 +00:00
|
|
|
)
|
|
|
|
|
2019-03-31 16:50:06 +00:00
|
|
|
// New creates a fifo at the given path, and returns an open function for reading.
|
|
|
|
// The fifo must not exist already, or that it's already a fifo file
|
|
|
|
//
|
|
|
|
// It returns a reader open function that may block until a writer opens
|
|
|
|
// so it's advised to run it in a goroutine different from reader goroutine
|
|
|
|
func New(path string) (func() (io.ReadCloser, error), error) {
|
|
|
|
// create first
|
|
|
|
if err := mkfifo(path, 0600); err != nil && !os.IsExist(err) {
|
|
|
|
return nil, fmt.Errorf("error creating fifo %v: %v", path, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
openFn := func() (io.ReadCloser, error) {
|
|
|
|
return os.OpenFile(path, unix.O_RDONLY, os.ModeNamedPipe)
|
|
|
|
}
|
|
|
|
|
|
|
|
return openFn, nil
|
2018-09-17 17:15:48 +00:00
|
|
|
}
|
|
|
|
|
2019-03-31 16:50:06 +00:00
|
|
|
// Open opens a fifo file for reading, assuming it already exists, returns io.WriteCloser
|
|
|
|
func Open(path string) (io.WriteCloser, error) {
|
|
|
|
return os.OpenFile(path, unix.O_WRONLY, os.ModeNamedPipe)
|
2018-09-17 17:15:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Remove a fifo that already exists at a given path
|
|
|
|
func Remove(path string) error {
|
|
|
|
return os.Remove(path)
|
|
|
|
}
|
|
|
|
|
|
|
|
func IsClosedErr(err error) bool {
|
|
|
|
err2, ok := err.(*os.PathError)
|
|
|
|
if ok {
|
|
|
|
return err2.Err == os.ErrClosed
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
2019-03-31 16:50:06 +00:00
|
|
|
|
|
|
|
func mkfifo(path string, mode uint32) (err error) {
|
|
|
|
return unix.Mkfifo(path, mode)
|
|
|
|
}
|