Commit a0f7c6c6 authored by Brian Dellisanti's avatar Brian Dellisanti Committed by Ian Lance Taylor

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
parent 6d1face5
...@@ -204,6 +204,12 @@ func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) { ...@@ -204,6 +204,12 @@ func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) {
return pw, nil 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. // Run starts the specified command and waits for it to complete.
// //
// The returned error is nil if the command runs, has no problems // The returned error is nil if the command runs, has no problems
...@@ -233,6 +239,8 @@ func (c *Cmd) Start() error { ...@@ -233,6 +239,8 @@ func (c *Cmd) Start() error {
for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} { for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} {
fd, err := setupFd(c) fd, err := setupFd(c)
if err != nil { if err != nil {
c.closeDescriptors(c.closeAfterStart)
c.closeDescriptors(c.closeAfterWait)
return err return err
} }
c.childFiles = append(c.childFiles, fd) c.childFiles = append(c.childFiles, fd)
...@@ -247,12 +255,12 @@ func (c *Cmd) Start() error { ...@@ -247,12 +255,12 @@ func (c *Cmd) Start() error {
Sys: c.SysProcAttr, Sys: c.SysProcAttr,
}) })
if err != nil { if err != nil {
c.closeDescriptors(c.closeAfterStart)
c.closeDescriptors(c.closeAfterWait)
return err return err
} }
for _, fd := range c.closeAfterStart { c.closeDescriptors(c.closeAfterStart)
fd.Close()
}
c.errch = make(chan error, len(c.goroutine)) c.errch = make(chan error, len(c.goroutine))
for _, fn := range c.goroutine { for _, fn := range c.goroutine {
...@@ -301,9 +309,7 @@ func (c *Cmd) Wait() error { ...@@ -301,9 +309,7 @@ func (c *Cmd) Wait() error {
} }
} }
for _, fd := range c.closeAfterWait { c.closeDescriptors(c.closeAfterWait)
fd.Close()
}
if err != nil { if err != nil {
return err return err
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment