From 4d15577783aaf5d6c3b53850d44b38b1bef305bc Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Thu, 2 Jun 2011 10:26:09 -0700 Subject: exec: add Cmd methods StdinPipe, StdoutPipe, StderrPipe It gets annoying to do this in caller code otherwise, especially having to remember to Close one side. R=rsc CC=golang-dev https://golang.org/cl/4517134 --- src/pkg/exec/exec.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) (limited to 'src/pkg/exec/exec.go') diff --git a/src/pkg/exec/exec.go b/src/pkg/exec/exec.go index ede09091db..958245832d 100644 --- a/src/pkg/exec/exec.go +++ b/src/pkg/exec/exec.go @@ -65,8 +65,8 @@ type Cmd struct { process *os.Process finished bool // when Wait was called childFiles []*os.File - closeAfterStart []*os.File - closeAfterWait []*os.File + closeAfterStart []io.Closer + closeAfterWait []io.Closer goroutine []func() os.Error errch chan os.Error // one send per goroutine } @@ -307,3 +307,60 @@ func (c *Cmd) CombinedOutput() ([]byte, os.Error) { err := c.Run() return b.Bytes(), err } + +// StdinPipe returns a pipe that will be connected to the command's +// standard input when the command starts. +func (c *Cmd) StdinPipe() (io.WriteCloser, os.Error) { + if c.Stdin != nil { + return nil, os.NewError("exec: Stdin already set") + } + if c.process != nil { + return nil, os.NewError("exec: StdinPipe after process started") + } + pr, pw, err := os.Pipe() + if err != nil { + return nil, err + } + c.Stdin = pr + c.closeAfterStart = append(c.closeAfterStart, pr) + c.closeAfterWait = append(c.closeAfterStart, pw) + return pw, nil +} + +// StdoutPipe returns a pipe that will be connected to the command's +// standard output when the command starts. +func (c *Cmd) StdoutPipe() (io.Reader, os.Error) { + if c.Stdout != nil { + return nil, os.NewError("exec: Stdout already set") + } + if c.process != nil { + return nil, os.NewError("exec: StdoutPipe after process started") + } + pr, pw, err := os.Pipe() + if err != nil { + return nil, err + } + c.Stdout = pw + c.closeAfterStart = append(c.closeAfterStart, pw) + c.closeAfterWait = append(c.closeAfterStart, pr) + return pr, nil +} + +// StderrPipe returns a pipe that will be connected to the command's +// standard error when the command starts. +func (c *Cmd) StderrPipe() (io.Reader, os.Error) { + if c.Stderr != nil { + return nil, os.NewError("exec: Stderr already set") + } + if c.process != nil { + return nil, os.NewError("exec: StderrPipe after process started") + } + pr, pw, err := os.Pipe() + if err != nil { + return nil, err + } + c.Stderr = pw + c.closeAfterStart = append(c.closeAfterStart, pw) + c.closeAfterWait = append(c.closeAfterStart, pr) + return pr, nil +} -- cgit v1.3