56 lines
1.2 KiB
Go
56 lines
1.2 KiB
Go
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
|
|
|
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
"syscall"
|
|
)
|
|
|
|
func setup_fifo(fn string) (chan string, error) {
|
|
commands := make(chan string)
|
|
if fn == "" {
|
|
return commands, nil
|
|
}
|
|
if info, err := os.Lstat(fn); err == nil {
|
|
if info.Mode()&os.ModeNamedPipe == 0 {
|
|
return commands, fmt.Errorf("FIFO path %q already exists and is not a FIFO", fn)
|
|
}
|
|
if err := os.Remove(fn); err != nil {
|
|
return commands, err
|
|
}
|
|
} else if !os.IsNotExist(err) {
|
|
return commands, err
|
|
}
|
|
if err := syscall.Mkfifo(fn, 0600); err != nil {
|
|
return commands, err
|
|
}
|
|
file, err := os.OpenFile(fn, os.O_RDWR, os.ModeNamedPipe)
|
|
if err != nil {
|
|
return commands, err
|
|
}
|
|
go readFIFO(file, commands)
|
|
return commands, nil
|
|
}
|
|
|
|
// readFIFO forwards complete commands and terminates on EOF or any read
|
|
// failure. Retrying an unrecoverable FIFO error used to spin a CPU forever.
|
|
func readFIFO(fh io.ReadCloser, out chan<- string) {
|
|
defer fh.Close()
|
|
defer close(out)
|
|
reader := bufio.NewReader(fh)
|
|
for {
|
|
line, err := reader.ReadBytes('\n')
|
|
if len(line) != 0 {
|
|
out <- strings.TrimSpace(string(line))
|
|
}
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|