]> Cypherpunks repositories - gostls13.git/commitdiff
os/exec: close all internal descriptors when Cmd.Start() fails.
authorBrian Dellisanti <briandellisanti@gmail.com>
Fri, 27 Apr 2012 22:46:49 +0000 (15:46 -0700)
committerIan Lance Taylor <iant@golang.org>
Fri, 27 Apr 2012 22:46:49 +0000 (15:46 -0700)
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

src/pkg/os/exec/exec.go

index bbd04902b742d289a806f86aff7dc54ddbe8a34d..9a8e1817014beb8e621017e0ae8ea6c538a47068 100644 (file)
@@ -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