diff options
author | Rick Arnold <rickarnoldjr@gmail.com> | 2013-08-13 11:04:09 -0700 |
---|---|---|
committer | Rick Arnold <rickarnoldjr@gmail.com> | 2013-08-13 11:04:09 -0700 |
commit | 3ed244076420d5970e622b5b407011c47c1723d1 (patch) | |
tree | 3859db90b26c71e839974f20bd557ddeb1a9f65a /src/pkg/io | |
parent | 82cc649b4006d80bffb81cc71ebc8a34a51e9ed1 (diff) | |
download | go-3ed244076420d5970e622b5b407011c47c1723d1.tar.gz |
io: prevent write to PipeWriter after Close
Return an ErrClosedPipe rather than allowing the write to proceed.
Fixes issue 5330.
R=golang-dev, rsc
CC=golang-dev
https://codereview.appspot.com/12541053
Committer: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/pkg/io')
-rw-r--r-- | src/pkg/io/pipe.go | 4 | ||||
-rw-r--r-- | src/pkg/io/pipe_test.go | 32 |
2 files changed, 36 insertions, 0 deletions
diff --git a/src/pkg/io/pipe.go b/src/pkg/io/pipe.go index f3f0f1757..f65354a7f 100644 --- a/src/pkg/io/pipe.go +++ b/src/pkg/io/pipe.go @@ -74,6 +74,10 @@ func (p *pipe) write(b []byte) (n int, err error) { p.l.Lock() defer p.l.Unlock() + if p.werr != nil { + err = ErrClosedPipe + return + } p.data = b p.rwait.Signal() for { diff --git a/src/pkg/io/pipe_test.go b/src/pkg/io/pipe_test.go index 7718151b0..b16e65306 100644 --- a/src/pkg/io/pipe_test.go +++ b/src/pkg/io/pipe_test.go @@ -268,3 +268,35 @@ func TestWriteNil(t *testing.T) { ReadFull(r, b[0:2]) r.Close() } + +func TestWriteAfterWriterClose(t *testing.T) { + r, w := Pipe() + + done := make(chan bool) + var writeErr error + go func() { + _, err := w.Write([]byte("hello")) + if err != nil { + t.Errorf("got error: %q; expected none", err) + } + w.Close() + _, writeErr = w.Write([]byte("world")) + done <- true + }() + + buf := make([]byte, 100) + var result string + n, err := ReadFull(r, buf) + if err != nil && err != ErrUnexpectedEOF { + t.Fatalf("got: %q; want: %q", err, ErrUnexpectedEOF) + } + result = string(buf[0:n]) + <-done + + if result != "hello" { + t.Errorf("got: %q; want: %q", result, "hello") + } + if writeErr != ErrClosedPipe { + t.Errorf("got: %q; want: %q", writeErr, ErrClosedPipe) + } +} |