mirror of
https://github.com/golang/go
synced 2024-11-23 14:40:02 -07:00
os/exec: ignore some pipe write errors on windows
This change is windows version of CL 12152. It also extends test to cover scenarios reported on issue #20445. Some source files copied and renamed to make code clearer. Fixes #20445 Change-Id: Idd2f636f27c6bd5cfe98017ba2df911358263382 Reviewed-on: https://go-review.googlesource.com/43910 Run-TryBot: Alex Brainman <alex.brainman@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
5f4f7519b6
commit
f3f29d1dea
@ -877,25 +877,41 @@ func TestHelperProcess(*testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
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{}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !plan9
|
||||
// +build !plan9,!windows
|
||||
|
||||
package exec
|
||||
|
23
src/os/exec/exec_windows.go
Normal file
23
src/os/exec/exec_windows.go
Normal file
@ -0,0 +1,23 @@
|
||||
// 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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user