Skip to content

Commit 73ca459

Browse files
committed
os/exec: ignore pipe write errors when command completes successfully
Fixes #9173 Change-Id: I83530533db84b07cb88dbf6ec690be48a06a9d7d Reviewed-on: https://go-review.googlesource.com/12152 Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 3c5eb96 commit 73ca459

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

src/os/exec/exec.go

+10
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,16 @@ func (c *Cmd) stdin() (f *os.File, err error) {
180180
c.closeAfterWait = append(c.closeAfterWait, pw)
181181
c.goroutine = append(c.goroutine, func() error {
182182
_, err := io.Copy(pw, c.Stdin)
183+
184+
// Ignore EPIPE errors copying to stdin if the program
185+
// completed successfully otherwise.
186+
// See Issue 9173.
187+
if pe, ok := err.(*os.PathError); ok &&
188+
pe.Op == "write" && pe.Path == "|1" &&
189+
pe.Err == syscall.EPIPE {
190+
err = nil
191+
}
192+
183193
if err1 := pw.Close(); err == nil {
184194
err = err1
185195
}

src/os/exec/exec_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -765,3 +765,24 @@ func TestHelperProcess(*testing.T) {
765765
os.Exit(2)
766766
}
767767
}
768+
769+
// Issue 9173: ignore stdin pipe writes if the program completes successfully.
770+
func TestIgnorePipeErrorOnSuccess(t *testing.T) {
771+
testenv.MustHaveExec(t)
772+
773+
// We really only care about testing this on Unixy things.
774+
if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
775+
t.Skipf("skipping test on %q", runtime.GOOS)
776+
}
777+
778+
cmd := helperCommand(t, "echo", "foo")
779+
var out bytes.Buffer
780+
cmd.Stdin = strings.NewReader(strings.Repeat("x", 10<<20))
781+
cmd.Stdout = &out
782+
if err := cmd.Run(); err != nil {
783+
t.Fatal(err)
784+
}
785+
if got, want := out.String(), "foo\n"; got != want {
786+
t.Errorf("output = %q; want %q", got, want)
787+
}
788+
}

0 commit comments

Comments
 (0)