1
0
mirror of https://github.com/golang/go synced 2024-11-23 10:20:03 -07:00

os/exec: close read pipe if copy to io.Writer fails

Fixes #10400.

Change-Id: Ic486cb8af4c40660fd1a2e3d10986975acba3f19
Reviewed-on: https://go-review.googlesource.com/12537
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Russ Cox 2015-07-22 16:50:00 -04:00
parent a5caa7c94e
commit 92390e47d8
2 changed files with 31 additions and 0 deletions

View File

@ -230,6 +230,7 @@ func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) {
c.closeAfterWait = append(c.closeAfterWait, pr)
c.goroutine = append(c.goroutine, func() error {
_, err := io.Copy(w, pr)
pr.Close() // in case io.Copy stopped due to write error
return err
})
return pw, nil

View File

@ -786,3 +786,33 @@ func TestIgnorePipeErrorOnSuccess(t *testing.T) {
t.Errorf("output = %q; want %q", got, want)
}
}
type badWriter struct{}
func (w *badWriter) Write(data []byte) (int, error) {
return 0, io.ErrUnexpectedEOF
}
func TestClosePipeOnCopyError(t *testing.T) {
testenv.MustHaveExec(t)
if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
t.Skipf("skipping test on %s - no yes command", runtime.GOOS)
}
cmd := exec.Command("yes")
cmd.Stdout = new(badWriter)
c := make(chan int, 1)
go func() {
err := cmd.Run()
if err == nil {
t.Errorf("yes completed successfully")
}
c <- 1
}()
select {
case <-c:
// ok
case <-time.After(5 * time.Second):
t.Fatalf("yes got stuck writing to bad writer")
}
}