Commit a877e81c authored by Mikio Hara's avatar Mikio Hara

net: don't return io.EOF on reading data from datagram, raw sockets on windows

Preventing returning io.EOF on non-connection oriented sockets is
already applied to Unix variants. This CL applies it to Windows.

Update #4856.

Change-Id: I82071d40f617e2962d0540b9d1d6a10ea4cdb2ec
Reviewed-on: https://go-review.googlesource.com/2203Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
Reviewed-by: 's avatarAlex Brainman <alex.brainman@gmail.com>
parent a4568016
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
package net
import (
"io"
"syscall"
)
// eofError returns io.EOF when fd is available for reading end of
// file.
func (fd *netFD) eofError(n int, err error) error {
if n == 0 && err == nil && fd.sotype != syscall.SOCK_DGRAM && fd.sotype != syscall.SOCK_RAW {
return io.EOF
}
return err
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
package net package net
...@@ -12,13 +12,12 @@ import ( ...@@ -12,13 +12,12 @@ import (
"testing" "testing"
) )
var chkReadErrTests = []struct { var eofErrorTests = []struct {
n int n int
err error err error
fd *netFD fd *netFD
expected error expected error
}{ }{
{100, nil, &netFD{sotype: syscall.SOCK_STREAM}, nil}, {100, nil, &netFD{sotype: syscall.SOCK_STREAM}, nil},
{100, io.EOF, &netFD{sotype: syscall.SOCK_STREAM}, io.EOF}, {100, io.EOF, &netFD{sotype: syscall.SOCK_STREAM}, io.EOF},
{100, errClosing, &netFD{sotype: syscall.SOCK_STREAM}, errClosing}, {100, errClosing, &netFD{sotype: syscall.SOCK_STREAM}, errClosing},
...@@ -48,11 +47,11 @@ var chkReadErrTests = []struct { ...@@ -48,11 +47,11 @@ var chkReadErrTests = []struct {
{0, errClosing, &netFD{sotype: syscall.SOCK_RAW}, errClosing}, {0, errClosing, &netFD{sotype: syscall.SOCK_RAW}, errClosing},
} }
func TestChkReadErr(t *testing.T) { func TestEOFError(t *testing.T) {
for _, tt := range chkReadErrTests { for _, tt := range eofErrorTests {
actual := chkReadErr(tt.n, tt.err, tt.fd) actual := tt.fd.eofError(tt.n, tt.err)
if actual != tt.expected { if actual != tt.expected {
t.Errorf("chkReadError(%v, %v, %v): expected %v, actual %v", tt.n, tt.err, tt.fd.sotype, tt.expected, actual) t.Errorf("eofError(%v, %v, %v): expected %v, actual %v", tt.n, tt.err, tt.fd.sotype, tt.expected, actual)
} }
} }
} }
...@@ -244,7 +244,7 @@ func (fd *netFD) Read(p []byte) (n int, err error) { ...@@ -244,7 +244,7 @@ func (fd *netFD) Read(p []byte) (n int, err error) {
} }
} }
} }
err = chkReadErr(n, err, fd) err = fd.eofError(n, err)
break break
} }
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
...@@ -271,7 +271,7 @@ func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) { ...@@ -271,7 +271,7 @@ func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
} }
} }
} }
err = chkReadErr(n, err, fd) err = fd.eofError(n, err)
break break
} }
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
...@@ -298,7 +298,7 @@ func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S ...@@ -298,7 +298,7 @@ func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S
} }
} }
} }
err = chkReadErr(n, err, fd) err = fd.eofError(n, err)
break break
} }
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
...@@ -307,13 +307,6 @@ func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S ...@@ -307,13 +307,6 @@ func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S
return return
} }
func chkReadErr(n int, err error, fd *netFD) error {
if n == 0 && err == nil && fd.sotype != syscall.SOCK_DGRAM && fd.sotype != syscall.SOCK_RAW {
return io.EOF
}
return err
}
func (fd *netFD) Write(p []byte) (nn int, err error) { func (fd *netFD) Write(p []byte) (nn int, err error) {
if err := fd.writeLock(); err != nil { if err := fd.writeLock(); err != nil {
return 0, err return 0, err
......
...@@ -6,7 +6,6 @@ package net ...@@ -6,7 +6,6 @@ package net
import ( import (
"errors" "errors"
"io"
"os" "os"
"runtime" "runtime"
"sync" "sync"
...@@ -468,12 +467,10 @@ func (fd *netFD) Read(buf []byte) (int, error) { ...@@ -468,12 +467,10 @@ func (fd *netFD) Read(buf []byte) (int, error) {
n, err := rsrv.ExecIO(o, "WSARecv", func(o *operation) error { n, err := rsrv.ExecIO(o, "WSARecv", func(o *operation) error {
return syscall.WSARecv(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil) return syscall.WSARecv(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
}) })
if err == nil && n == 0 {
err = io.EOF
}
if raceenabled { if raceenabled {
raceAcquire(unsafe.Pointer(&ioSync)) raceAcquire(unsafe.Pointer(&ioSync))
} }
err = fd.eofError(n, err)
return n, err return n, err
} }
...@@ -494,6 +491,7 @@ func (fd *netFD) readFrom(buf []byte) (n int, sa syscall.Sockaddr, err error) { ...@@ -494,6 +491,7 @@ func (fd *netFD) readFrom(buf []byte) (n int, sa syscall.Sockaddr, err error) {
o.rsan = int32(unsafe.Sizeof(*o.rsa)) o.rsan = int32(unsafe.Sizeof(*o.rsa))
return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil) return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
}) })
err = fd.eofError(n, err)
if err != nil { if err != nil {
return 0, nil, err return 0, nil, err
} }
......
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