]> Cypherpunks repositories - gostls13.git/commitdiff
os/exec: ignore pipe write errors when command completes successfully
authorBrad Fitzpatrick <bradfitz@golang.org>
Tue, 14 Jul 2015 00:17:24 +0000 (18:17 -0600)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 14 Jul 2015 00:41:31 +0000 (00:41 +0000)
Fixes #9173

Change-Id: I83530533db84b07cb88dbf6ec690be48a06a9d7d
Reviewed-on: https://go-review.googlesource.com/12152
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/os/exec/exec.go
src/os/exec/exec_test.go

index a263795814f3d2c1dd618a592d31c06ff886767b..e3c6fb62b11f8af81fa983c1ddc68ab6879cb6e8 100644 (file)
@@ -180,6 +180,16 @@ func (c *Cmd) stdin() (f *os.File, err error) {
        c.closeAfterWait = append(c.closeAfterWait, pw)
        c.goroutine = append(c.goroutine, func() error {
                _, err := io.Copy(pw, c.Stdin)
+
+               // Ignore EPIPE errors copying to stdin if the program
+               // completed successfully otherwise.
+               // See Issue 9173.
+               if pe, ok := err.(*os.PathError); ok &&
+                       pe.Op == "write" && pe.Path == "|1" &&
+                       pe.Err == syscall.EPIPE {
+                       err = nil
+               }
+
                if err1 := pw.Close(); err == nil {
                        err = err1
                }
index 96d41cbc8ec70258a9b9df965caf9660ec68647c..6888d29cd8f5005028cb9237e4253f6f9ac9df41 100644 (file)
@@ -765,3 +765,24 @@ func TestHelperProcess(*testing.T) {
                os.Exit(2)
        }
 }
+
+// Issue 9173: ignore stdin pipe writes if the program completes successfully.
+func TestIgnorePipeErrorOnSuccess(t *testing.T) {
+       testenv.MustHaveExec(t)
+
+       // We really only care about testing this on Unixy things.
+       if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
+               t.Skipf("skipping test on %q", runtime.GOOS)
+       }
+
+       cmd := helperCommand(t, "echo", "foo")
+       var out bytes.Buffer
+       cmd.Stdin = strings.NewReader(strings.Repeat("x", 10<<20))
+       cmd.Stdout = &out
+       if err := cmd.Run(); err != nil {
+               t.Fatal(err)
+       }
+       if got, want := out.String(), "foo\n"; got != want {
+               t.Errorf("output = %q; want %q", got, want)
+       }
+}