aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/exec/exec.go
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2011-06-02 10:26:09 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2011-06-02 10:26:09 -0700
commit4d15577783aaf5d6c3b53850d44b38b1bef305bc (patch)
tree95fcebd58b873a1fb07565b4b5032e8fc167189a /src/pkg/exec/exec.go
parent69cb8fef43aba1d133d093c4617c5711c1b5a20b (diff)
downloadgo-4d15577783aaf5d6c3b53850d44b38b1bef305bc.tar.xz
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
Diffstat (limited to 'src/pkg/exec/exec.go')
-rw-r--r--src/pkg/exec/exec.go61
1 files changed, 59 insertions, 2 deletions
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
+}