// +build windows package hcs import ( "net" "time" "github.com/Microsoft/go-winio" "github.com/pkg/errors" ) type IO struct { stdin net.Conn stdout net.Conn stderr net.Conn terminal bool } // NewIO connects to the provided pipe addresses func NewIO(stdin, stdout, stderr string, terminal bool) (*IO, error) { var ( c net.Conn err error io IO ) defer func() { if err != nil { io.Close() } }() for _, p := range []struct { name string open bool conn *net.Conn }{ { name: stdin, open: stdin != "", conn: &io.stdin, }, { name: stdout, open: stdout != "", conn: &io.stdout, }, { name: stderr, open: !terminal && stderr != "", conn: &io.stderr, }, } { if p.open { dialTimeout := 3 * time.Second c, err = winio.DialPipe(p.name, &dialTimeout) if err != nil { return nil, errors.Wrapf(err, "failed to connect to %s", p.name) } *p.conn = c } } return &io, nil } // Close terminates all successfully dialed IO connections func (i *IO) Close() { for _, cn := range []net.Conn{i.stdin, i.stdout, i.stderr} { if cn != nil { cn.Close() cn = nil } } }