diff options
Diffstat (limited to 'libgo/go/net/tcpsock_posix.go')
-rw-r--r-- | libgo/go/net/tcpsock_posix.go | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/libgo/go/net/tcpsock_posix.go b/libgo/go/net/tcpsock_posix.go index 200ce91566c..e05bc10170e 100644 --- a/libgo/go/net/tcpsock_posix.go +++ b/libgo/go/net/tcpsock_posix.go @@ -9,6 +9,7 @@ package net import ( + "fmt" "io" "os" "syscall" @@ -26,6 +27,11 @@ func sockaddrToTCP(sa syscall.Sockaddr) Addr { return &TCPAddr{sa.Addr[0:], sa.Port} case *syscall.SockaddrInet6: return &TCPAddr{sa.Addr[0:], sa.Port} + default: + if sa != nil { + // Diagnose when we will turn a non-nil sockaddr into a nil. + panic(fmt.Sprintf("unexpected type in sockaddrToTCP: %T", sa)) + } } return nil } @@ -70,7 +76,7 @@ func (c *TCPConn) ok() bool { return c != nil && c.fd != nil } // Read implements the Conn Read method. func (c *TCPConn) Read(b []byte) (n int, err error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } return c.fd.Read(b) } @@ -86,7 +92,7 @@ func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) { // Write implements the Conn Write method. func (c *TCPConn) Write(b []byte) (n int, err error) { if !c.ok() { - return 0, os.EINVAL + return 0, syscall.EINVAL } return c.fd.Write(b) } @@ -94,7 +100,7 @@ func (c *TCPConn) Write(b []byte) (n int, err error) { // Close closes the TCP connection. func (c *TCPConn) Close() error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } err := c.fd.Close() c.fd = nil @@ -105,7 +111,7 @@ func (c *TCPConn) Close() error { // Most callers should just use Close. func (c *TCPConn) CloseRead() error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return c.fd.CloseRead() } @@ -114,7 +120,7 @@ func (c *TCPConn) CloseRead() error { // Most callers should just use Close. func (c *TCPConn) CloseWrite() error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return c.fd.CloseWrite() } @@ -138,7 +144,7 @@ func (c *TCPConn) RemoteAddr() Addr { // SetDeadline implements the Conn SetDeadline method. func (c *TCPConn) SetDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setDeadline(c.fd, t) } @@ -146,7 +152,7 @@ func (c *TCPConn) SetDeadline(t time.Time) error { // SetReadDeadline implements the Conn SetReadDeadline method. func (c *TCPConn) SetReadDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setReadDeadline(c.fd, t) } @@ -154,7 +160,7 @@ func (c *TCPConn) SetReadDeadline(t time.Time) error { // SetWriteDeadline implements the Conn SetWriteDeadline method. func (c *TCPConn) SetWriteDeadline(t time.Time) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setWriteDeadline(c.fd, t) } @@ -163,7 +169,7 @@ func (c *TCPConn) SetWriteDeadline(t time.Time) error { // receive buffer associated with the connection. func (c *TCPConn) SetReadBuffer(bytes int) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setReadBuffer(c.fd, bytes) } @@ -172,7 +178,7 @@ func (c *TCPConn) SetReadBuffer(bytes int) error { // transmit buffer associated with the connection. func (c *TCPConn) SetWriteBuffer(bytes int) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setWriteBuffer(c.fd, bytes) } @@ -190,7 +196,7 @@ func (c *TCPConn) SetWriteBuffer(bytes int) error { // data to be sent and acknowledged. func (c *TCPConn) SetLinger(sec int) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setLinger(c.fd, sec) } @@ -199,7 +205,7 @@ func (c *TCPConn) SetLinger(sec int) error { // keepalive messages on the connection. func (c *TCPConn) SetKeepAlive(keepalive bool) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setKeepAlive(c.fd, keepalive) } @@ -210,7 +216,7 @@ func (c *TCPConn) SetKeepAlive(keepalive bool) error { // that data is sent as soon as possible after a Write. func (c *TCPConn) SetNoDelay(noDelay bool) error { if !c.ok() { - return os.EINVAL + return syscall.EINVAL } return setNoDelay(c.fd, noDelay) } @@ -259,6 +265,17 @@ func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) { } func selfConnect(fd *netFD) bool { + // The socket constructor can return an fd with raddr nil under certain + // unknown conditions. The errors in the calls there to Getpeername + // are discarded, but we can't catch the problem there because those + // calls are sometimes legally erroneous with a "socket not connected". + // Since this code (selfConnect) is already trying to work around + // a problem, we make sure if this happens we recognize trouble and + // ask the DialTCP routine to try again. + // TODO: try to understand what's really going on. + if fd.laddr == nil || fd.raddr == nil { + return true + } l := fd.laddr.(*TCPAddr) r := fd.raddr.(*TCPAddr) return l.Port == r.Port && l.IP.Equal(r.IP) @@ -294,7 +311,7 @@ func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) { // and the remote address. func (l *TCPListener) AcceptTCP() (c *TCPConn, err error) { if l == nil || l.fd == nil || l.fd.sysfd < 0 { - return nil, os.EINVAL + return nil, syscall.EINVAL } fd, err := l.fd.accept(sockaddrToTCP) if err != nil { @@ -317,7 +334,7 @@ func (l *TCPListener) Accept() (c Conn, err error) { // Already Accepted connections are not closed. func (l *TCPListener) Close() error { if l == nil || l.fd == nil { - return os.EINVAL + return syscall.EINVAL } return l.fd.Close() } @@ -329,7 +346,7 @@ func (l *TCPListener) Addr() Addr { return l.fd.laddr } // A zero time value disables the deadline. func (l *TCPListener) SetDeadline(t time.Time) error { if l == nil || l.fd == nil { - return os.EINVAL + return syscall.EINVAL } return setDeadline(l.fd, t) } |