Neale Pickett
·
2016-01-18
readwritecloserwrapper.go
1package main
2
3import (
4 "io"
5 "os/exec"
6 "log"
7)
8
9type ReadWriteCloserWrapper struct {
10 Reader io.ReadCloser
11 Writer io.WriteCloser
12 cmd *exec.Cmd
13}
14
15func NewReadWriteCloseWrapper(r io.ReadCloser, w io.WriteCloser) *ReadWriteCloserWrapper {
16 return &ReadWriteCloserWrapper{r, w, nil}
17}
18
19func (w *ReadWriteCloserWrapper) Close() (error) {
20 err1 := w.Reader.Close()
21 err2 := w.Writer.Close()
22 if w.cmd != nil{
23 w.cmd.Wait()
24 }
25
26 switch {
27 case err1 != nil:
28 return err1
29 case err2 != nil:
30 return err2
31 }
32 return nil
33}
34
35func (w *ReadWriteCloserWrapper) Read(p []byte) (n int, err error) {
36 n, err = w.Reader.Read(p)
37 return
38}
39
40func (w *ReadWriteCloserWrapper) Write(p []byte) (n int, err error) {
41 n, err = w.Writer.Write(p)
42 return
43}
44
45func StartStdioProcess(name string, args []string) (w *ReadWriteCloserWrapper, err error) {
46 w = new(ReadWriteCloserWrapper)
47
48 cmd := exec.Command(name, args...)
49
50 if cmd == nil {
51 log.Fatalf("Can't run command: %v %v", name, args)
52 }
53
54 w.Reader, err = cmd.StdoutPipe()
55 if err != nil {
56 return nil, err
57 }
58
59 w.Writer, err = cmd.StdinPipe()
60 if err != nil {
61 w.Reader.Close()
62 return nil, err
63 }
64
65 if err = cmd.Start(); err != nil {
66 w.Reader.Close()
67 w.Writer.Close()
68 return nil, err
69 }
70
71 w.cmd = cmd
72
73 return
74}