}
}
+type delayedInfiniteReader struct{}
+
+func (delayedInfiniteReader) Read(b []byte) (int, error) {
+ time.Sleep(100 * time.Millisecond)
+ for i := range b {
+ b[i] = 'x'
+ }
+ return len(b), nil
+}
+
// 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" {
+ // We really only care about testing this on Unixy and Windowsy things.
+ if 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)
+ testWith := func(r io.Reader) func(*testing.T) {
+ return func(t *testing.T) {
+ cmd := helperCommand(t, "echo", "foo")
+ var out bytes.Buffer
+ cmd.Stdin = r
+ 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)
+ }
+ }
}
+ t.Run("10MB", testWith(strings.NewReader(strings.Repeat("x", 10<<20))))
+ t.Run("Infinite", testWith(delayedInfiniteReader{}))
}
type badWriter struct{}
--- /dev/null
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package exec
+
+import (
+ "os"
+ "syscall"
+)
+
+func init() {
+ skipStdinCopyError = func(err error) bool {
+ // Ignore ERROR_BROKEN_PIPE and ERROR_NO_DATA errors copying
+ // to stdin if the program completed successfully otherwise.
+ // See Issue 20445.
+ const _ERROR_NO_DATA = syscall.Errno(0xe8)
+ pe, ok := err.(*os.PathError)
+ return ok &&
+ pe.Op == "write" && pe.Path == "|1" &&
+ (pe.Err == syscall.ERROR_BROKEN_PIPE || pe.Err == _ERROR_NO_DATA)
+ }
+}