spongy/spongyd/readwritecloserwrapper.go

75 lines
1.2 KiB
Go

package main
import (
"io"
"os/exec"
"log"
)
type ReadWriteCloserWrapper struct {
Reader io.ReadCloser
Writer io.WriteCloser
cmd *exec.Cmd
}
func NewReadWriteCloseWrapper(r io.ReadCloser, w io.WriteCloser) *ReadWriteCloserWrapper {
return &ReadWriteCloserWrapper{r, w, nil}
}
func (w *ReadWriteCloserWrapper) Close() (error) {
err1 := w.Reader.Close()
err2 := w.Writer.Close()
if w.cmd != nil{
w.cmd.Wait()
}
switch {
case err1 != nil:
return err1
case err2 != nil:
return err2
}
return nil
}
func (w *ReadWriteCloserWrapper) Read(p []byte) (n int, err error) {
n, err = w.Reader.Read(p)
return
}
func (w *ReadWriteCloserWrapper) Write(p []byte) (n int, err error) {
n, err = w.Writer.Write(p)
return
}
func StartStdioProcess(name string, args []string) (w *ReadWriteCloserWrapper, err error) {
w = new(ReadWriteCloserWrapper)
cmd := exec.Command(name, args...)
if cmd == nil {
log.Fatalf("Can't run command: %v %v", name, args)
}
w.Reader, err = cmd.StdoutPipe()
if err != nil {
return nil, err
}
w.Writer, err = cmd.StdinPipe()
if err != nil {
w.Reader.Close()
return nil, err
}
if err = cmd.Start(); err != nil {
w.Reader.Close()
w.Writer.Close()
return nil, err
}
w.cmd = cmd
return
}