Commit 92390e47 authored by Russ Cox's avatar Russ Cox

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

Fixes #10400.

Change-Id: Ic486cb8af4c40660fd1a2e3d10986975acba3f19
Reviewed-on: https://go-review.googlesource.com/12537Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent a5caa7c9
......@@ -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
......
......@@ -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")
}
}
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