mirror of
https://github.com/golang/go
synced 2024-11-18 06:44:49 -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,18 +877,30 @@ 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.
|
// Issue 9173: ignore stdin pipe writes if the program completes successfully.
|
||||||
func TestIgnorePipeErrorOnSuccess(t *testing.T) {
|
func TestIgnorePipeErrorOnSuccess(t *testing.T) {
|
||||||
testenv.MustHaveExec(t)
|
testenv.MustHaveExec(t)
|
||||||
|
|
||||||
// We really only care about testing this on Unixy things.
|
// We really only care about testing this on Unixy and Windowsy things.
|
||||||
if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
|
if runtime.GOOS == "plan9" {
|
||||||
t.Skipf("skipping test on %q", runtime.GOOS)
|
t.Skipf("skipping test on %q", runtime.GOOS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testWith := func(r io.Reader) func(*testing.T) {
|
||||||
|
return func(t *testing.T) {
|
||||||
cmd := helperCommand(t, "echo", "foo")
|
cmd := helperCommand(t, "echo", "foo")
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
cmd.Stdin = strings.NewReader(strings.Repeat("x", 10<<20))
|
cmd.Stdin = r
|
||||||
cmd.Stdout = &out
|
cmd.Stdout = &out
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -897,6 +909,10 @@ func TestIgnorePipeErrorOnSuccess(t *testing.T) {
|
|||||||
t.Errorf("output = %q; want %q", 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{}
|
type badWriter struct{}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build !plan9
|
// +build !plan9,!windows
|
||||||
|
|
||||||
package exec
|
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