summaryrefslogtreecommitdiff
path: root/src/pkg/io
diff options
context:
space:
mode:
authorRick Arnold <rickarnoldjr@gmail.com>2013-08-13 11:04:09 -0700
committerRick Arnold <rickarnoldjr@gmail.com>2013-08-13 11:04:09 -0700
commit3ed244076420d5970e622b5b407011c47c1723d1 (patch)
tree3859db90b26c71e839974f20bd557ddeb1a9f65a /src/pkg/io
parent82cc649b4006d80bffb81cc71ebc8a34a51e9ed1 (diff)
downloadgo-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.go4
-rw-r--r--src/pkg/io/pipe_test.go32
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)
+ }
+}