I'm trying to wrap an executable that takes an input and output file paths as arguments, such that it will be possible to provide the input and output as stdin
and stdout
.
I've written a short script in Go that attempts to do this, but for some reason which eludes me, it hangs forever.
See https://goplay.space/#le6Hexg1ZiJ.
I can add more details as required, but to start, I'd rather not pollute the question with possibly less relevant information.
EDIT: As requested, I'm adding the code here.
package main
import (
"bytes"
"io"
"log"
"os"
"strings"
"syscall"
"golang.org/x/sync/errgroup"
)
/*
Expected behavior:
# Terminal 1
$ go run main.go
# Terminal 2
$ cat inPipe > outPipe
The go program is writing to inPipe and reading from outPipe
Actual behavior: The program stalls
*/
func main() {
eg := &errgroup.Group{}
inPipe := "inPipe"
outPipe := "outPipe"
if err := syscall.Mkfifo(inPipe, 0644); err != nil {
log.Fatal(err)
}
defer os.Remove(inPipe)
if err := syscall.Mkfifo(outPipe, 0644); err != nil {
log.Fatal(err)
}
defer os.Remove(outPipe)
fIn, err := os.OpenFile(inPipe, os.O_WRONLY, os.ModeNamedPipe)
if err != nil {
log.Fatal(err)
}
defer fIn.Close()
eg.Go(func() error {
_, err := io.Copy(fIn, strings.NewReader("123"))
return err
})
fOut, err := os.OpenFile(outPipe, os.O_RDONLY, os.ModeNamedPipe)
if err != nil {
log.Fatal(err)
}
defer fOut.Close()
buf := &bytes.Buffer{}
eg.Go(func() error {
_, err := io.Copy(buf, fOut)
return err
})
if err := eg.Wait(); err != nil {
log.Fatal(err)
}
if _, err := io.Copy(os.Stdout, buf); err != nil {
log.Fatal(err)
}
}