From b906df653b58bc2ab9b93e18f62adccc8c1419b7 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 15 Nov 2016 17:55:28 -0800 Subject: os/exec: add closeOnce.WriteString method Add an explicit WriteString method to closeOnce that acquires the writers lock. This overrides the one promoted from the embedded *os.File field. The promoted one naturally does not acquire the lock, and can therefore race with the Close method. Fixes #17647. Change-Id: I3460f2a0d503449481cfb2fd4628b4855ab0ecdf Reviewed-on: https://go-review.googlesource.com/33298 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/os/exec/exec_test.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src/os/exec/exec_test.go') diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go index 67fe14faae..d3ac7ab4b9 100644 --- a/src/os/exec/exec_test.go +++ b/src/os/exec/exec_test.go @@ -246,6 +246,32 @@ func TestStdinClose(t *testing.T) { check("Wait", cmd.Wait()) } +// Issue 17647. +func TestStdinCloseRace(t *testing.T) { + cmd := helperCommand(t, "stdinClose") + stdin, err := cmd.StdinPipe() + if err != nil { + t.Fatalf("StdinPipe: %v", err) + } + if err := cmd.Start(); err != nil { + t.Fatalf("Start: %v", err) + } + go func() { + if err := cmd.Process.Kill(); err != nil { + t.Errorf("Kill: %v", err) + } + }() + go func() { + io.Copy(stdin, strings.NewReader(stdinCloseTestString)) + if err := stdin.Close(); err != nil { + t.Errorf("stdin.Close: %v", err) + } + }() + if err := cmd.Wait(); err == nil { + t.Fatalf("Wait: succeeded unexpectedly") + } +} + // Issue 5071 func TestPipeLookPathLeak(t *testing.T) { fd0, lsof0 := numOpenFDS(t) -- cgit v1.3