aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/os/exec
diff options
context:
space:
mode:
authorBrian Dellisanti <briandellisanti@gmail.com>2012-04-27 15:46:49 -0700
committerIan Lance Taylor <iant@golang.org>2012-04-27 15:46:49 -0700
commita0f7c6c658327e1b306d7328c28c99d15f9d3216 (patch)
tree6e9e679d588d0fb90dceec7f08f4ff3842bed36c /src/pkg/os/exec
parent6d1face5bad19dc101d4b05ed0cd3b1116952186 (diff)
downloadgo-a0f7c6c658327e1b306d7328c28c99d15f9d3216.tar.xz
os/exec: close all internal descriptors when Cmd.Start() fails.
This closes any internal descriptors (pipes, etc) that Cmd.Start() had opened before it failed. Fixes #3468. R=golang-dev, iant, bradfitz CC=golang-dev https://golang.org/cl/5986044
Diffstat (limited to 'src/pkg/os/exec')
-rw-r--r--src/pkg/os/exec/exec.go18
1 files changed, 12 insertions, 6 deletions
diff --git a/src/pkg/os/exec/exec.go b/src/pkg/os/exec/exec.go
index bbd04902b7..9a8e181701 100644
--- a/src/pkg/os/exec/exec.go
+++ b/src/pkg/os/exec/exec.go
@@ -204,6 +204,12 @@ func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) {
return pw, nil
}
+func (c *Cmd) closeDescriptors(closers []io.Closer) {
+ for _, fd := range closers {
+ fd.Close()
+ }
+}
+
// Run starts the specified command and waits for it to complete.
//
// The returned error is nil if the command runs, has no problems
@@ -233,6 +239,8 @@ func (c *Cmd) Start() error {
for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} {
fd, err := setupFd(c)
if err != nil {
+ c.closeDescriptors(c.closeAfterStart)
+ c.closeDescriptors(c.closeAfterWait)
return err
}
c.childFiles = append(c.childFiles, fd)
@@ -247,12 +255,12 @@ func (c *Cmd) Start() error {
Sys: c.SysProcAttr,
})
if err != nil {
+ c.closeDescriptors(c.closeAfterStart)
+ c.closeDescriptors(c.closeAfterWait)
return err
}
- for _, fd := range c.closeAfterStart {
- fd.Close()
- }
+ c.closeDescriptors(c.closeAfterStart)
c.errch = make(chan error, len(c.goroutine))
for _, fn := range c.goroutine {
@@ -301,9 +309,7 @@ func (c *Cmd) Wait() error {
}
}
- for _, fd := range c.closeAfterWait {
- fd.Close()
- }
+ c.closeDescriptors(c.closeAfterWait)
if err != nil {
return err