Commit fd34e78b authored by Russ Cox's avatar Russ Cox

various: reduce overuse of os.EINVAL + others

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5372081
parent 7af553ab
...@@ -10,7 +10,6 @@ import ( ...@@ -10,7 +10,6 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"os"
"strings" "strings"
"testing" "testing"
"testing/iotest" "testing/iotest"
...@@ -425,9 +424,9 @@ var errorWriterTests = []errorWriterTest{ ...@@ -425,9 +424,9 @@ var errorWriterTests = []errorWriterTest{
{0, 1, nil, io.ErrShortWrite}, {0, 1, nil, io.ErrShortWrite},
{1, 2, nil, io.ErrShortWrite}, {1, 2, nil, io.ErrShortWrite},
{1, 1, nil, nil}, {1, 1, nil, nil},
{0, 1, os.EPIPE, os.EPIPE}, {0, 1, io.ErrClosedPipe, io.ErrClosedPipe},
{1, 2, os.EPIPE, os.EPIPE}, {1, 2, io.ErrClosedPipe, io.ErrClosedPipe},
{1, 1, os.EPIPE, os.EPIPE}, {1, 1, io.ErrClosedPipe, io.ErrClosedPipe},
} }
func TestWriteErrors(t *testing.T) { func TestWriteErrors(t *testing.T) {
......
...@@ -19,7 +19,6 @@ import ( ...@@ -19,7 +19,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"os"
) )
// Order specifies the bit ordering in an LZW data stream. // Order specifies the bit ordering in an LZW data stream.
...@@ -212,8 +211,10 @@ func (d *decoder) flush() { ...@@ -212,8 +211,10 @@ func (d *decoder) flush() {
d.o = 0 d.o = 0
} }
var errClosed = errors.New("compress/lzw: reader/writer is closed")
func (d *decoder) Close() error { func (d *decoder) Close() error {
d.err = os.EINVAL // in case any Reads come along d.err = errClosed // in case any Reads come along
return nil return nil
} }
......
...@@ -9,7 +9,6 @@ import ( ...@@ -9,7 +9,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"os"
) )
// A writer is a buffered, flushable writer. // A writer is a buffered, flushable writer.
...@@ -64,7 +63,7 @@ type encoder struct { ...@@ -64,7 +63,7 @@ type encoder struct {
// call. It is equal to invalidCode if there was no such call. // call. It is equal to invalidCode if there was no such call.
savedCode uint32 savedCode uint32
// err is the first error encountered during writing. Closing the encoder // err is the first error encountered during writing. Closing the encoder
// will make any future Write calls return os.EINVAL. // will make any future Write calls return errClosed
err error err error
// table is the hash table from 20-bit keys to 12-bit values. Each table // table is the hash table from 20-bit keys to 12-bit values. Each table
// entry contains key<<12|val and collisions resolve by linear probing. // entry contains key<<12|val and collisions resolve by linear probing.
...@@ -191,13 +190,13 @@ loop: ...@@ -191,13 +190,13 @@ loop:
// flush e's underlying writer. // flush e's underlying writer.
func (e *encoder) Close() error { func (e *encoder) Close() error {
if e.err != nil { if e.err != nil {
if e.err == os.EINVAL { if e.err == errClosed {
return nil return nil
} }
return e.err return e.err
} }
// Make any future calls to Write return os.EINVAL. // Make any future calls to Write return errClosed.
e.err = os.EINVAL e.err = errClosed
// Write the savedCode if valid. // Write the savedCode if valid.
if e.savedCode != invalidCode { if e.savedCode != invalidCode {
if err := e.write(e, e.savedCode); err != nil { if err := e.write(e, e.savedCode); err != nil {
......
...@@ -50,10 +50,6 @@ func testFile(t *testing.T, fn string, order Order, litWidth int) { ...@@ -50,10 +50,6 @@ func testFile(t *testing.T, fn string, order Order, litWidth int) {
return return
} }
_, err1 := lzww.Write(b[:n]) _, err1 := lzww.Write(b[:n])
if err1 == os.EPIPE {
// Fail, but do not report the error, as some other (presumably reportable) error broke the pipe.
return
}
if err1 != nil { if err1 != nil {
t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1) t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1)
return return
......
...@@ -59,10 +59,6 @@ func testLevelDict(t *testing.T, fn string, b0 []byte, level int, d string) { ...@@ -59,10 +59,6 @@ func testLevelDict(t *testing.T, fn string, b0 []byte, level int, d string) {
} }
defer zlibw.Close() defer zlibw.Close()
_, err = zlibw.Write(b0) _, err = zlibw.Write(b0)
if err == os.EPIPE {
// Fail, but do not report the error, as some other (presumably reported) error broke the pipe.
return
}
if err != nil { if err != nil {
t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err) t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
return return
......
...@@ -5,16 +5,16 @@ ...@@ -5,16 +5,16 @@
package rand package rand
import ( import (
"errors"
"io" "io"
"math/big" "math/big"
"os"
) )
// Prime returns a number, p, of the given size, such that p is prime // Prime returns a number, p, of the given size, such that p is prime
// with high probability. // with high probability.
func Prime(rand io.Reader, bits int) (p *big.Int, err error) { func Prime(rand io.Reader, bits int) (p *big.Int, err error) {
if bits < 1 { if bits < 1 {
err = os.EINVAL err = errors.New("crypto/rand: prime size must be positive")
} }
b := uint(bits % 8) b := uint(bits % 8)
......
...@@ -93,7 +93,8 @@ func (c *Conn) SetTimeout(nsec int64) error { ...@@ -93,7 +93,8 @@ func (c *Conn) SetTimeout(nsec int64) error {
} }
// SetReadTimeout sets the time (in nanoseconds) that // SetReadTimeout sets the time (in nanoseconds) that
// Read will wait for data before returning os.EAGAIN. // Read will wait for data before returning a net.Error
// with Timeout() == true.
// Setting nsec == 0 (the default) disables the deadline. // Setting nsec == 0 (the default) disables the deadline.
func (c *Conn) SetReadTimeout(nsec int64) error { func (c *Conn) SetReadTimeout(nsec int64) error {
return c.conn.SetReadTimeout(nsec) return c.conn.SetReadTimeout(nsec)
...@@ -737,7 +738,7 @@ func (c *Conn) Write(b []byte) (n int, err error) { ...@@ -737,7 +738,7 @@ func (c *Conn) Write(b []byte) (n int, err error) {
return c.writeRecord(recordTypeApplicationData, b) return c.writeRecord(recordTypeApplicationData, b)
} }
// Read can be made to time out and return err == os.EAGAIN // Read can be made to time out and return a net.Error with Timeout() == true
// after a fixed time limit; see SetTimeout and SetReadTimeout. // after a fixed time limit; see SetTimeout and SetReadTimeout.
func (c *Conn) Read(b []byte) (n int, err error) { func (c *Conn) Read(b []byte) (n int, err error) {
if err = c.Handshake(); err != nil { if err = c.Handshake(); err != nil {
......
...@@ -7,7 +7,6 @@ package xml ...@@ -7,7 +7,6 @@ package xml
import ( import (
"bytes" "bytes"
"io" "io"
"os"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
...@@ -205,7 +204,7 @@ func (d *downCaser) ReadByte() (c byte, err error) { ...@@ -205,7 +204,7 @@ func (d *downCaser) ReadByte() (c byte, err error) {
func (d *downCaser) Read(p []byte) (int, error) { func (d *downCaser) Read(p []byte) (int, error) {
d.t.Fatalf("unexpected Read call on downCaser reader") d.t.Fatalf("unexpected Read call on downCaser reader")
return 0, os.EINVAL panic("unreachable")
} }
func TestRawTokenAltEncoding(t *testing.T) { func TestRawTokenAltEncoding(t *testing.T) {
......
...@@ -4,10 +4,7 @@ ...@@ -4,10 +4,7 @@
package tiff package tiff
import ( import "io"
"io"
"os"
)
// buffer buffers an io.Reader to satisfy io.ReaderAt. // buffer buffers an io.Reader to satisfy io.ReaderAt.
type buffer struct { type buffer struct {
...@@ -19,7 +16,7 @@ func (b *buffer) ReadAt(p []byte, off int64) (int, error) { ...@@ -19,7 +16,7 @@ func (b *buffer) ReadAt(p []byte, off int64) (int, error) {
o := int(off) o := int(off)
end := o + len(p) end := o + len(p)
if int64(end) != off+int64(len(p)) { if int64(end) != off+int64(len(p)) {
return 0, os.EINVAL return 0, io.ErrUnexpectedEOF
} }
m := len(b.buf) m := len(b.buf)
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
package syslog package syslog
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
"net" "net"
...@@ -75,7 +76,7 @@ func Dial(network, raddr string, priority Priority, prefix string) (w *Writer, e ...@@ -75,7 +76,7 @@ func Dial(network, raddr string, priority Priority, prefix string) (w *Writer, e
// Write sends a log message to the syslog daemon. // Write sends a log message to the syslog daemon.
func (w *Writer) Write(b []byte) (int, error) { func (w *Writer) Write(b []byte) (int, error) {
if w.priority > LOG_DEBUG || w.priority < LOG_EMERG { if w.priority > LOG_DEBUG || w.priority < LOG_EMERG {
return 0, os.EINVAL return 0, errors.New("log/syslog: invalid priority")
} }
return w.conn.writeBytes(w.priority, w.prefix, b) return w.conn.writeBytes(w.priority, w.prefix, b)
} }
......
...@@ -160,7 +160,7 @@ type sliceReaderAt []byte ...@@ -160,7 +160,7 @@ type sliceReaderAt []byte
func (r sliceReaderAt) ReadAt(b []byte, off int64) (int, error) { func (r sliceReaderAt) ReadAt(b []byte, off int64) (int, error) {
if int(off) >= len(r) || off < 0 { if int(off) >= len(r) || off < 0 {
return 0, os.EINVAL return 0, io.ErrUnexpectedEOF
} }
n := copy(b, r[int(off):]) n := copy(b, r[int(off):])
return n, nil return n, nil
......
...@@ -22,6 +22,10 @@ var ( ...@@ -22,6 +22,10 @@ var (
ErrPipeline = &http.ProtocolError{"pipeline error"} ErrPipeline = &http.ProtocolError{"pipeline error"}
) )
// This is an API usage error - the local side is closed.
// ErrPersistEOF (above) reports that the remote side is closed.
var errClosed = errors.New("i/o operation on closed connection")
// A ServerConn reads requests and sends responses over an underlying // A ServerConn reads requests and sends responses over an underlying
// connection, until the HTTP keepalive logic commands an end. ServerConn // connection, until the HTTP keepalive logic commands an end. ServerConn
// also allows hijacking the underlying connection by calling Hijack // also allows hijacking the underlying connection by calling Hijack
...@@ -108,7 +112,7 @@ func (sc *ServerConn) Read() (req *http.Request, err error) { ...@@ -108,7 +112,7 @@ func (sc *ServerConn) Read() (req *http.Request, err error) {
} }
if sc.r == nil { // connection closed by user in the meantime if sc.r == nil { // connection closed by user in the meantime
defer sc.lk.Unlock() defer sc.lk.Unlock()
return nil, os.EBADF return nil, errClosed
} }
r := sc.r r := sc.r
lastbody := sc.lastbody lastbody := sc.lastbody
...@@ -313,7 +317,7 @@ func (cc *ClientConn) Write(req *http.Request) (err error) { ...@@ -313,7 +317,7 @@ func (cc *ClientConn) Write(req *http.Request) (err error) {
} }
if cc.c == nil { // connection closed by user in the meantime if cc.c == nil { // connection closed by user in the meantime
defer cc.lk.Unlock() defer cc.lk.Unlock()
return os.EBADF return errClosed
} }
c := cc.c c := cc.c
if req.Close { if req.Close {
...@@ -369,7 +373,7 @@ func (cc *ClientConn) Read(req *http.Request) (resp *http.Response, err error) { ...@@ -369,7 +373,7 @@ func (cc *ClientConn) Read(req *http.Request) (resp *http.Response, err error) {
} }
if cc.r == nil { // connection closed by user in the meantime if cc.r == nil { // connection closed by user in the meantime
defer cc.lk.Unlock() defer cc.lk.Unlock()
return nil, os.EBADF return nil, errClosed
} }
r := cc.r r := cc.r
lastbody := cc.lastbody lastbody := cc.lastbody
......
...@@ -504,7 +504,7 @@ func (pc *persistConn) expectingResponse() bool { ...@@ -504,7 +504,7 @@ func (pc *persistConn) expectingResponse() bool {
var remoteSideClosedFunc func(error) bool // or nil to use default var remoteSideClosedFunc func(error) bool // or nil to use default
func remoteSideClosed(err error) bool { func remoteSideClosed(err error) bool {
if err == io.EOF || err == os.EINVAL { if err == io.EOF {
return true return true
} }
if remoteSideClosedFunc != nil { if remoteSideClosedFunc != nil {
......
...@@ -13,7 +13,6 @@ package tabwriter ...@@ -13,7 +13,6 @@ package tabwriter
import ( import (
"bytes" "bytes"
"io" "io"
"os"
"unicode/utf8" "unicode/utf8"
) )
...@@ -221,7 +220,7 @@ type osError struct { ...@@ -221,7 +220,7 @@ type osError struct {
func (b *Writer) write0(buf []byte) { func (b *Writer) write0(buf []byte) {
n, err := b.output.Write(buf) n, err := b.output.Write(buf)
if n != len(buf) && err == nil { if n != len(buf) && err == nil {
err = os.EIO err = io.ErrShortWrite
} }
if err != nil { if err != nil {
panic(osError{err}) panic(osError{err})
......
...@@ -10,12 +10,12 @@ import ( ...@@ -10,12 +10,12 @@ import (
"bufio" "bufio"
"crypto/tls" "crypto/tls"
"encoding/json" "encoding/json"
"errors"
"io" "io"
"io/ioutil" "io/ioutil"
"net" "net"
"net/http" "net/http"
"net/url" "net/url"
"os"
"sync" "sync"
) )
...@@ -243,12 +243,14 @@ func (ws *Conn) RemoteAddr() net.Addr { ...@@ -243,12 +243,14 @@ func (ws *Conn) RemoteAddr() net.Addr {
return &Addr{ws.config.Origin} return &Addr{ws.config.Origin}
} }
var errSetTimeout = errors.New("websocket: cannot set timeout: not using a net.Conn")
// SetTimeout sets the connection's network timeout in nanoseconds. // SetTimeout sets the connection's network timeout in nanoseconds.
func (ws *Conn) SetTimeout(nsec int64) error { func (ws *Conn) SetTimeout(nsec int64) error {
if conn, ok := ws.rwc.(net.Conn); ok { if conn, ok := ws.rwc.(net.Conn); ok {
return conn.SetTimeout(nsec) return conn.SetTimeout(nsec)
} }
return os.EINVAL return errSetTimeout
} }
// SetReadTimeout sets the connection's network read timeout in nanoseconds. // SetReadTimeout sets the connection's network read timeout in nanoseconds.
...@@ -256,7 +258,7 @@ func (ws *Conn) SetReadTimeout(nsec int64) error { ...@@ -256,7 +258,7 @@ func (ws *Conn) SetReadTimeout(nsec int64) error {
if conn, ok := ws.rwc.(net.Conn); ok { if conn, ok := ws.rwc.(net.Conn); ok {
return conn.SetReadTimeout(nsec) return conn.SetReadTimeout(nsec)
} }
return os.EINVAL return errSetTimeout
} }
// SetWriteTimeout sets the connection's network write timeout in nanoseconds. // SetWriteTimeout sets the connection's network write timeout in nanoseconds.
...@@ -264,7 +266,7 @@ func (ws *Conn) SetWriteTimeout(nsec int64) error { ...@@ -264,7 +266,7 @@ func (ws *Conn) SetWriteTimeout(nsec int64) error {
if conn, ok := ws.rwc.(net.Conn); ok { if conn, ok := ws.rwc.(net.Conn); ok {
return conn.SetWriteTimeout(nsec) return conn.SetWriteTimeout(nsec)
} }
return os.EINVAL return errSetTimeout
} }
// Config returns the WebSocket config. // Config returns the WebSocket config.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment