Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
c06cf03f
Commit
c06cf03f
authored
Nov 01, 2011
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
io: use error, add EOF, avoid os
R=r, r CC=golang-dev
https://golang.org/cl/5311068
parent
c14f71c7
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
110 additions
and
107 deletions
+110
-107
src/pkg/io/io.go
src/pkg/io/io.go
+55
-47
src/pkg/io/io_test.go
src/pkg/io/io_test.go
+9
-10
src/pkg/io/multi.go
src/pkg/io/multi.go
+6
-8
src/pkg/io/multi_test.go
src/pkg/io/multi_test.go
+3
-4
src/pkg/io/pipe.go
src/pkg/io/pipe.go
+25
-25
src/pkg/io/pipe_test.go
src/pkg/io/pipe_test.go
+12
-13
No files found.
src/pkg/io/io.go
View file @
c06cf03f
This diff is collapsed.
Click to expand it.
src/pkg/io/io_test.go
View file @
c06cf03f
...
...
@@ -7,7 +7,6 @@ package io_test
import
(
"bytes"
.
"io"
"os"
"strings"
"testing"
)
...
...
@@ -85,7 +84,7 @@ type noReadFrom struct {
w
Writer
}
func
(
w
*
noReadFrom
)
Write
(
p
[]
byte
)
(
n
int
,
err
os
.
E
rror
)
{
func
(
w
*
noReadFrom
)
Write
(
p
[]
byte
)
(
n
int
,
err
e
rror
)
{
return
w
.
w
.
Write
(
p
)
}
...
...
@@ -101,7 +100,7 @@ func TestCopyNEOF(t *testing.T) {
}
n
,
err
=
CopyN
(
&
noReadFrom
{
b
},
strings
.
NewReader
(
"foo"
),
4
)
if
n
!=
3
||
err
!=
os
.
EOF
{
if
n
!=
3
||
err
!=
EOF
{
t
.
Errorf
(
"CopyN(noReadFrom, foo, 4) = %d, %v; want 3, EOF"
,
n
,
err
)
}
...
...
@@ -111,7 +110,7 @@ func TestCopyNEOF(t *testing.T) {
}
n
,
err
=
CopyN
(
b
,
strings
.
NewReader
(
"foo"
),
4
)
// b has read from
if
n
!=
3
||
err
!=
os
.
EOF
{
if
n
!=
3
||
err
!=
EOF
{
t
.
Errorf
(
"CopyN(bytes.Buffer, foo, 4) = %d, %v; want 3, EOF"
,
n
,
err
)
}
}
...
...
@@ -121,16 +120,16 @@ func TestReadAtLeast(t *testing.T) {
testReadAtLeast
(
t
,
&
rb
)
}
// A version of bytes.Buffer that returns n > 0,
os.
EOF on Read
// A version of bytes.Buffer that returns n > 0, EOF on Read
// when the input is exhausted.
type
dataAndEOFBuffer
struct
{
bytes
.
Buffer
}
func
(
r
*
dataAndEOFBuffer
)
Read
(
p
[]
byte
)
(
n
int
,
err
os
.
E
rror
)
{
func
(
r
*
dataAndEOFBuffer
)
Read
(
p
[]
byte
)
(
n
int
,
err
e
rror
)
{
n
,
err
=
r
.
Buffer
.
Read
(
p
)
if
n
>
0
&&
r
.
Buffer
.
Len
()
==
0
&&
err
==
nil
{
err
=
os
.
EOF
err
=
EOF
}
return
}
...
...
@@ -162,7 +161,7 @@ func testReadAtLeast(t *testing.T, rb ReadWriter) {
t
.
Errorf
(
"expected to have read 2 bytes, got %v"
,
n
)
}
n
,
err
=
ReadAtLeast
(
rb
,
buf
,
2
)
if
err
!=
os
.
EOF
{
if
err
!=
EOF
{
t
.
Errorf
(
"expected EOF, got %v"
,
err
)
}
if
n
!=
0
{
...
...
@@ -193,14 +192,14 @@ func TestTeeReader(t *testing.T) {
if
!
bytes
.
Equal
(
wb
.
Bytes
(),
src
)
{
t
.
Errorf
(
"bytes written = %q want %q"
,
wb
.
Bytes
(),
src
)
}
if
n
,
err
:=
r
.
Read
(
dst
);
n
!=
0
||
err
!=
os
.
EOF
{
if
n
,
err
:=
r
.
Read
(
dst
);
n
!=
0
||
err
!=
EOF
{
t
.
Errorf
(
"r.Read at EOF = %d, %v want 0, EOF"
,
n
,
err
)
}
rb
=
bytes
.
NewBuffer
(
src
)
pr
,
pw
:=
Pipe
()
pr
.
Close
()
r
=
TeeReader
(
rb
,
pw
)
if
n
,
err
:=
ReadFull
(
r
,
dst
);
n
!=
0
||
err
!=
os
.
EPIPE
{
if
n
,
err
:=
ReadFull
(
r
,
dst
);
n
!=
0
||
err
!=
ErrClosedPipe
{
t
.
Errorf
(
"closed tee: ReadFull(r, dst) = %d, %v; want 0, EPIPE"
,
n
,
err
)
}
}
src/pkg/io/multi.go
View file @
c06cf03f
...
...
@@ -4,17 +4,15 @@
package
io
import
"os"
type
multiReader
struct
{
readers
[]
Reader
}
func
(
mr
*
multiReader
)
Read
(
p
[]
byte
)
(
n
int
,
err
os
.
E
rror
)
{
func
(
mr
*
multiReader
)
Read
(
p
[]
byte
)
(
n
int
,
err
e
rror
)
{
for
len
(
mr
.
readers
)
>
0
{
n
,
err
=
mr
.
readers
[
0
]
.
Read
(
p
)
if
n
>
0
||
err
!=
os
.
EOF
{
if
err
==
os
.
EOF
{
if
n
>
0
||
err
!=
EOF
{
if
err
==
EOF
{
// Don't return EOF yet. There may be more bytes
// in the remaining readers.
err
=
nil
...
...
@@ -23,12 +21,12 @@ func (mr *multiReader) Read(p []byte) (n int, err os.Error) {
}
mr
.
readers
=
mr
.
readers
[
1
:
]
}
return
0
,
os
.
EOF
return
0
,
EOF
}
// MultiReader returns a Reader that's the logical concatenation of
// the provided input readers. They're read sequentially. Once all
// inputs are drained, Read will return
os.
EOF.
// inputs are drained, Read will return EOF.
func
MultiReader
(
readers
...
Reader
)
Reader
{
return
&
multiReader
{
readers
}
}
...
...
@@ -37,7 +35,7 @@ type multiWriter struct {
writers
[]
Writer
}
func
(
t
*
multiWriter
)
Write
(
p
[]
byte
)
(
n
int
,
err
os
.
E
rror
)
{
func
(
t
*
multiWriter
)
Write
(
p
[]
byte
)
(
n
int
,
err
e
rror
)
{
for
_
,
w
:=
range
t
.
writers
{
n
,
err
=
w
.
Write
(
p
)
if
err
!=
nil
{
...
...
src/pkg/io/multi_test.go
View file @
c06cf03f
...
...
@@ -9,7 +9,6 @@ import (
"bytes"
"crypto/sha1"
"fmt"
"os"
"strings"
"testing"
)
...
...
@@ -26,7 +25,7 @@ func TestMultiReader(t *testing.T) {
buf
=
make
([]
byte
,
20
)
tests
()
}
expectRead
:=
func
(
size
int
,
expected
string
,
eerr
os
.
E
rror
)
{
expectRead
:=
func
(
size
int
,
expected
string
,
eerr
e
rror
)
{
nread
++
n
,
gerr
:=
mr
.
Read
(
buf
[
0
:
size
])
if
n
!=
len
(
expected
)
{
...
...
@@ -48,13 +47,13 @@ func TestMultiReader(t *testing.T) {
expectRead
(
2
,
"fo"
,
nil
)
expectRead
(
5
,
"o "
,
nil
)
expectRead
(
5
,
"bar"
,
nil
)
expectRead
(
5
,
""
,
os
.
EOF
)
expectRead
(
5
,
""
,
EOF
)
})
withFooBar
(
func
()
{
expectRead
(
4
,
"foo "
,
nil
)
expectRead
(
1
,
"b"
,
nil
)
expectRead
(
3
,
"ar"
,
nil
)
expectRead
(
1
,
""
,
os
.
EOF
)
expectRead
(
1
,
""
,
EOF
)
})
withFooBar
(
func
()
{
expectRead
(
5
,
"foo "
,
nil
)
...
...
src/pkg/io/pipe.go
View file @
c06cf03f
...
...
@@ -7,14 +7,14 @@
package
io
import
(
"os"
"sync"
)
import
"sync"
// ErrClosedPipe is the error used for read or write operations on a closed pipe.
var
ErrClosedPipe
=
&
Error
{
"io: read/write on closed pipe"
}
type
pipeResult
struct
{
n
int
err
os
.
E
rror
err
e
rror
}
// A pipe is the shared pipe structure underlying PipeReader and PipeWriter.
...
...
@@ -25,11 +25,11 @@ type pipe struct {
data
[]
byte
// data remaining in pending write
rwait
sync
.
Cond
// waiting reader
wwait
sync
.
Cond
// waiting writer
rerr
os
.
Error
// if reader closed, error to give writes
werr
os
.
Error
// if writer closed, error to give reads
rerr
error
// if reader closed, error to give writes
werr
error
// if writer closed, error to give reads
}
func
(
p
*
pipe
)
read
(
b
[]
byte
)
(
n
int
,
err
os
.
E
rror
)
{
func
(
p
*
pipe
)
read
(
b
[]
byte
)
(
n
int
,
err
e
rror
)
{
// One reader at a time.
p
.
rl
.
Lock
()
defer
p
.
rl
.
Unlock
()
...
...
@@ -38,7 +38,7 @@ func (p *pipe) read(b []byte) (n int, err os.Error) {
defer
p
.
l
.
Unlock
()
for
{
if
p
.
rerr
!=
nil
{
return
0
,
os
.
EINVAL
return
0
,
ErrClosedPipe
}
if
p
.
data
!=
nil
{
break
...
...
@@ -59,7 +59,7 @@ func (p *pipe) read(b []byte) (n int, err os.Error) {
var
zero
[
0
]
byte
func
(
p
*
pipe
)
write
(
b
[]
byte
)
(
n
int
,
err
os
.
E
rror
)
{
func
(
p
*
pipe
)
write
(
b
[]
byte
)
(
n
int
,
err
e
rror
)
{
// pipe uses nil to mean not available
if
b
==
nil
{
b
=
zero
[
:
]
...
...
@@ -82,7 +82,7 @@ func (p *pipe) write(b []byte) (n int, err os.Error) {
break
}
if
p
.
werr
!=
nil
{
err
=
os
.
EINVAL
err
=
ErrClosedPipe
}
p
.
wwait
.
Wait
()
}
...
...
@@ -91,9 +91,9 @@ func (p *pipe) write(b []byte) (n int, err os.Error) {
return
}
func
(
p
*
pipe
)
rclose
(
err
os
.
E
rror
)
{
func
(
p
*
pipe
)
rclose
(
err
e
rror
)
{
if
err
==
nil
{
err
=
os
.
EPIPE
err
=
ErrClosedPipe
}
p
.
l
.
Lock
()
defer
p
.
l
.
Unlock
()
...
...
@@ -102,9 +102,9 @@ func (p *pipe) rclose(err os.Error) {
p
.
wwait
.
Signal
()
}
func
(
p
*
pipe
)
wclose
(
err
os
.
E
rror
)
{
func
(
p
*
pipe
)
wclose
(
err
e
rror
)
{
if
err
==
nil
{
err
=
os
.
EOF
err
=
EOF
}
p
.
l
.
Lock
()
defer
p
.
l
.
Unlock
()
...
...
@@ -122,20 +122,20 @@ type PipeReader struct {
// it reads data from the pipe, blocking until a writer
// arrives or the write end is closed.
// If the write end is closed with an error, that error is
// returned as err; otherwise err is
os.
EOF.
func
(
r
*
PipeReader
)
Read
(
data
[]
byte
)
(
n
int
,
err
os
.
E
rror
)
{
// returned as err; otherwise err is EOF.
func
(
r
*
PipeReader
)
Read
(
data
[]
byte
)
(
n
int
,
err
e
rror
)
{
return
r
.
p
.
read
(
data
)
}
// Close closes the reader; subsequent writes to the
// write half of the pipe will return the error
os.EPIPE
.
func
(
r
*
PipeReader
)
Close
()
os
.
E
rror
{
// write half of the pipe will return the error
ErrClosedPipe
.
func
(
r
*
PipeReader
)
Close
()
e
rror
{
return
r
.
CloseWithError
(
nil
)
}
// CloseWithError closes the reader; subsequent writes
// to the write half of the pipe will return the error err.
func
(
r
*
PipeReader
)
CloseWithError
(
err
os
.
Error
)
os
.
E
rror
{
func
(
r
*
PipeReader
)
CloseWithError
(
err
error
)
e
rror
{
r
.
p
.
rclose
(
err
)
return
nil
}
...
...
@@ -149,20 +149,20 @@ type PipeWriter struct {
// it writes data to the pipe, blocking until readers
// have consumed all the data or the read end is closed.
// If the read end is closed with an error, that err is
// returned as err; otherwise err is
os.EPIPE
.
func
(
w
*
PipeWriter
)
Write
(
data
[]
byte
)
(
n
int
,
err
os
.
E
rror
)
{
// returned as err; otherwise err is
ErrClosedPipe
.
func
(
w
*
PipeWriter
)
Write
(
data
[]
byte
)
(
n
int
,
err
e
rror
)
{
return
w
.
p
.
write
(
data
)
}
// Close closes the writer; subsequent reads from the
// read half of the pipe will return no bytes and
os.
EOF.
func
(
w
*
PipeWriter
)
Close
()
os
.
E
rror
{
// read half of the pipe will return no bytes and EOF.
func
(
w
*
PipeWriter
)
Close
()
e
rror
{
return
w
.
CloseWithError
(
nil
)
}
// CloseWithError closes the writer; subsequent reads from the
// read half of the pipe will return no bytes and the error err.
func
(
w
*
PipeWriter
)
CloseWithError
(
err
os
.
Error
)
os
.
E
rror
{
func
(
w
*
PipeWriter
)
CloseWithError
(
err
error
)
e
rror
{
w
.
p
.
wclose
(
err
)
return
nil
}
...
...
src/pkg/io/pipe_test.go
View file @
c06cf03f
...
...
@@ -7,7 +7,6 @@ package io_test
import
(
"fmt"
.
"io"
"os"
"testing"
"time"
)
...
...
@@ -44,7 +43,7 @@ func reader(t *testing.T, r Reader, c chan int) {
var
buf
=
make
([]
byte
,
64
)
for
{
n
,
err
:=
r
.
Read
(
buf
)
if
err
==
os
.
EOF
{
if
err
==
EOF
{
c
<-
0
break
}
...
...
@@ -84,7 +83,7 @@ func TestPipe2(t *testing.T) {
type
pipeReturn
struct
{
n
int
err
os
.
E
rror
err
e
rror
}
// Test a large write that requires multiple reads to satisfy.
...
...
@@ -106,7 +105,7 @@ func TestPipe3(t *testing.T) {
tot
:=
0
for
n
:=
1
;
n
<=
256
;
n
*=
2
{
nn
,
err
:=
r
.
Read
(
rdat
[
tot
:
tot
+
n
])
if
err
!=
nil
&&
err
!=
os
.
EOF
{
if
err
!=
nil
&&
err
!=
EOF
{
t
.
Fatalf
(
"read: %v"
,
err
)
}
...
...
@@ -116,7 +115,7 @@ func TestPipe3(t *testing.T) {
expect
=
1
}
else
if
n
==
256
{
expect
=
0
if
err
!=
os
.
EOF
{
if
err
!=
EOF
{
t
.
Fatalf
(
"read at end: %v"
,
err
)
}
}
...
...
@@ -142,13 +141,13 @@ func TestPipe3(t *testing.T) {
// Test read after/before writer close.
type
closer
interface
{
CloseWithError
(
os
.
Error
)
os
.
E
rror
Close
()
os
.
E
rror
CloseWithError
(
error
)
e
rror
Close
()
e
rror
}
type
pipeTest
struct
{
async
bool
err
os
.
E
rror
err
e
rror
closeWithError
bool
}
...
...
@@ -167,7 +166,7 @@ var pipeTests = []pipeTest{
func
delayClose
(
t
*
testing
.
T
,
cl
closer
,
ch
chan
int
,
tt
pipeTest
)
{
time
.
Sleep
(
1e6
)
// 1 ms
var
err
os
.
E
rror
var
err
e
rror
if
tt
.
closeWithError
{
err
=
cl
.
CloseWithError
(
tt
.
err
)
}
else
{
...
...
@@ -193,7 +192,7 @@ func TestPipeReadClose(t *testing.T) {
<-
c
want
:=
tt
.
err
if
want
==
nil
{
want
=
os
.
EOF
want
=
EOF
}
if
err
!=
want
{
t
.
Errorf
(
"read from closed pipe: %v want %v"
,
err
,
want
)
...
...
@@ -214,8 +213,8 @@ func TestPipeReadClose2(t *testing.T) {
go
delayClose
(
t
,
r
,
c
,
pipeTest
{})
n
,
err
:=
r
.
Read
(
make
([]
byte
,
64
))
<-
c
if
n
!=
0
||
err
!=
os
.
EINVAL
{
t
.
Errorf
(
"read from closed pipe: %v, %v want %v, %v"
,
n
,
err
,
0
,
os
.
EINVAL
)
if
n
!=
0
||
err
!=
ErrClosedPipe
{
t
.
Errorf
(
"read from closed pipe: %v, %v want %v, %v"
,
n
,
err
,
0
,
ErrClosedPipe
)
}
}
...
...
@@ -234,7 +233,7 @@ func TestPipeWriteClose(t *testing.T) {
<-
c
expect
:=
tt
.
err
if
expect
==
nil
{
expect
=
os
.
EPIPE
expect
=
ErrClosedPipe
}
if
err
!=
expect
{
t
.
Errorf
(
"write on closed pipe: %v want %v"
,
err
,
expect
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment