diff options
Diffstat (limited to 'libgo/go/net/fd_windows.go')
-rw-r--r-- | libgo/go/net/fd_windows.go | 114 |
1 files changed, 51 insertions, 63 deletions
diff --git a/libgo/go/net/fd_windows.go b/libgo/go/net/fd_windows.go index f3a534a1de0..205daff9e46 100644 --- a/libgo/go/net/fd_windows.go +++ b/libgo/go/net/fd_windows.go @@ -5,8 +5,6 @@ package net import ( - "errors" - "io" "os" "runtime" "sync" @@ -40,7 +38,7 @@ func sysInit() { var d syscall.WSAData e := syscall.WSAStartup(uint32(0x202), &d) if e != nil { - initErr = os.NewSyscallError("WSAStartup", e) + initErr = os.NewSyscallError("wsastartup", e) } canCancelIO = syscall.LoadCancelIoEx() == nil if syscall.LoadGetAddrInfo() == nil { @@ -70,10 +68,6 @@ func sysInit() { } } -func closesocket(s syscall.Handle) error { - return syscall.Closesocket(s) -} - func canUseConnectEx(net string) bool { switch net { case "udp", "udp4", "udp6", "ip", "ip4", "ip6": @@ -159,7 +153,7 @@ func (s *ioSrv) ExecIO(o *operation, name string, submit func(o *operation) erro // Notify runtime netpoll about starting IO. err := fd.pd.Prepare(int(o.mode)) if err != nil { - return 0, &OpError{name, fd.net, fd.laddr, err} + return 0, err } // Start IO. if canCancelIO { @@ -182,7 +176,7 @@ func (s *ioSrv) ExecIO(o *operation, name string, submit func(o *operation) erro // IO started, and we have to wait for its completion. err = nil default: - return 0, &OpError{name, fd.net, fd.laddr, err} + return 0, err } // Wait for our request to complete. err = fd.pd.Wait(int(o.mode)) @@ -190,7 +184,7 @@ func (s *ioSrv) ExecIO(o *operation, name string, submit func(o *operation) erro // All is good. Extract our IO results and return. if o.errno != 0 { err = syscall.Errno(o.errno) - return 0, &OpError{name, fd.net, fd.laddr, err} + return 0, err } return int(o.qty), nil } @@ -221,7 +215,7 @@ func (s *ioSrv) ExecIO(o *operation, name string, submit func(o *operation) erro if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled err = netpollErr } - return 0, &OpError{name, fd.net, fd.laddr, err} + return 0, err } // We issued cancellation request. But, it seems, IO operation succeeded // before cancellation request run. We need to treat IO operation as @@ -303,7 +297,7 @@ func (fd *netFD) init() error { size := uint32(unsafe.Sizeof(flag)) err := syscall.WSAIoctl(fd.sysfd, syscall.SIO_UDP_CONNRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0) if err != nil { - return os.NewSyscallError("WSAIoctl", err) + return os.NewSyscallError("wsaioctl", err) } } fd.rop.mode = 'r' @@ -337,7 +331,7 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error { defer fd.setWriteDeadline(noDeadline) } if !canUseConnectEx(fd.net) { - return syscall.Connect(fd.sysfd, ra) + return os.NewSyscallError("connect", connectFunc(fd.sysfd, ra)) } // ConnectEx windows API requires an unconnected, previously bound socket. if la == nil { @@ -350,20 +344,23 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error { panic("unexpected type in connect") } if err := syscall.Bind(fd.sysfd, la); err != nil { - return err + return os.NewSyscallError("bind", err) } } // Call ConnectEx API. o := &fd.wop o.sa = ra _, err := wsrv.ExecIO(o, "ConnectEx", func(o *operation) error { - return syscall.ConnectEx(o.fd.sysfd, o.sa, nil, 0, nil, &o.o) + return connectExFunc(o.fd.sysfd, o.sa, nil, 0, nil, &o.o) }) if err != nil { + if _, ok := err.(syscall.Errno); ok { + err = os.NewSyscallError("connectex", err) + } return err } // Refresh socket properties. - return syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd))) + return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))) } func (fd *netFD) destroy() { @@ -371,9 +368,9 @@ func (fd *netFD) destroy() { return } // Poller may want to unregister fd in readiness notification mechanism, - // so this must be executed before closesocket. + // so this must be executed before closeFunc. fd.pd.Close() - closesocket(fd.sysfd) + closeFunc(fd.sysfd) fd.sysfd = syscall.InvalidHandle // no need for a finalizer anymore runtime.SetFinalizer(fd, nil) @@ -443,11 +440,7 @@ func (fd *netFD) shutdown(how int) error { return err } defer fd.decref() - err := syscall.Shutdown(fd.sysfd, how) - if err != nil { - return &OpError{"shutdown", fd.net, fd.laddr, err} - } - return nil + return syscall.Shutdown(fd.sysfd, how) } func (fd *netFD) closeRead() error { @@ -468,16 +461,17 @@ func (fd *netFD) Read(buf []byte) (int, 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) }) - if err == nil && n == 0 { - err = io.EOF - } if raceenabled { raceAcquire(unsafe.Pointer(&ioSync)) } + err = fd.eofError(n, err) + if _, ok := err.(syscall.Errno); ok { + err = os.NewSyscallError("wsarecv", err) + } return n, err } -func (fd *netFD) readFrom(buf []byte) (n int, sa syscall.Sockaddr, err error) { +func (fd *netFD) readFrom(buf []byte) (int, syscall.Sockaddr, error) { if len(buf) == 0 { return 0, nil, nil } @@ -487,18 +481,22 @@ func (fd *netFD) readFrom(buf []byte) (n int, sa syscall.Sockaddr, err error) { defer fd.readUnlock() o := &fd.rop o.InitBuf(buf) - n, err = rsrv.ExecIO(o, "WSARecvFrom", func(o *operation) error { + n, err := rsrv.ExecIO(o, "WSARecvFrom", func(o *operation) error { if o.rsa == nil { o.rsa = new(syscall.RawSockaddrAny) } 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) }) + err = fd.eofError(n, err) + if _, ok := err.(syscall.Errno); ok { + err = os.NewSyscallError("wsarecvfrom", err) + } if err != nil { - return 0, nil, err + return n, nil, err } - sa, _ = o.rsa.Sockaddr() - return + sa, _ := o.rsa.Sockaddr() + return n, sa, nil } func (fd *netFD) Write(buf []byte) (int, error) { @@ -511,9 +509,13 @@ func (fd *netFD) Write(buf []byte) (int, error) { } o := &fd.wop o.InitBuf(buf) - return wsrv.ExecIO(o, "WSASend", func(o *operation) error { + n, err := wsrv.ExecIO(o, "WSASend", func(o *operation) error { return syscall.WSASend(o.fd.sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil) }) + if _, ok := err.(syscall.Errno); ok { + err = os.NewSyscallError("wsasend", err) + } + return n, err } func (fd *netFD) writeTo(buf []byte, sa syscall.Sockaddr) (int, error) { @@ -527,23 +529,27 @@ func (fd *netFD) writeTo(buf []byte, sa syscall.Sockaddr) (int, error) { o := &fd.wop o.InitBuf(buf) o.sa = sa - return wsrv.ExecIO(o, "WSASendto", func(o *operation) error { + n, err := wsrv.ExecIO(o, "WSASendto", func(o *operation) error { return syscall.WSASendto(o.fd.sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil) }) + if _, ok := err.(syscall.Errno); ok { + err = os.NewSyscallError("wsasendto", err) + } + return n, err } func (fd *netFD) acceptOne(rawsa []syscall.RawSockaddrAny, o *operation) (*netFD, error) { // Get new socket. s, err := sysSocket(fd.family, fd.sotype, 0) if err != nil { - return nil, &OpError{"socket", fd.net, fd.laddr, err} + return nil, err } // Associate our new socket with IOCP. netfd, err := newFD(s, fd.family, fd.sotype, fd.net) if err != nil { - closesocket(s) - return nil, &OpError{"accept", fd.net, fd.laddr, err} + closeFunc(s) + return nil, err } if err := netfd.init(); err != nil { fd.Close() @@ -558,6 +564,9 @@ func (fd *netFD) acceptOne(rawsa []syscall.RawSockaddrAny, o *operation) (*netFD }) if err != nil { netfd.Close() + if _, ok := err.(syscall.Errno); ok { + err = os.NewSyscallError("acceptex", err) + } return nil, err } @@ -565,7 +574,7 @@ func (fd *netFD) acceptOne(rawsa []syscall.RawSockaddrAny, o *operation) (*netFD err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd))) if err != nil { netfd.Close() - return nil, &OpError{"Setsockopt", fd.net, fd.laddr, err} + return nil, os.NewSyscallError("setsockopt", err) } return netfd, nil @@ -591,11 +600,11 @@ func (fd *netFD) accept() (*netFD, error) { // before AcceptEx could complete. These errors relate to new // connection, not to AcceptEx, so ignore broken connection and // try AcceptEx again for more connections. - operr, ok := err.(*OpError) + nerr, ok := err.(*os.SyscallError) if !ok { return nil, err } - errno, ok := operr.Err.(syscall.Errno) + errno, ok := nerr.Err.(syscall.Errno) if !ok { return nil, err } @@ -619,38 +628,17 @@ func (fd *netFD) accept() (*netFD, error) { return netfd, nil } -func skipRawSocketTests() (skip bool, skipmsg string, err error) { - // From http://msdn.microsoft.com/en-us/library/windows/desktop/ms740548.aspx: - // Note: To use a socket of type SOCK_RAW requires administrative privileges. - // Users running Winsock applications that use raw sockets must be a member of - // the Administrators group on the local computer, otherwise raw socket calls - // will fail with an error code of WSAEACCES. On Windows Vista and later, access - // for raw sockets is enforced at socket creation. In earlier versions of Windows, - // access for raw sockets is enforced during other socket operations. - s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, 0) - if err == syscall.WSAEACCES { - return true, "skipping test; no access to raw socket allowed", nil - } - if err != nil { - return true, "", err - } - defer syscall.Closesocket(s) - return false, "", nil -} - // Unimplemented functions. func (fd *netFD) dup() (*os.File, error) { // TODO: Implement this - return nil, os.NewSyscallError("dup", syscall.EWINDOWS) + return nil, syscall.EWINDOWS } -var errNoSupport = errors.New("address family not supported") - func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) { - return 0, 0, 0, nil, errNoSupport + return 0, 0, 0, nil, syscall.EWINDOWS } func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) { - return 0, 0, errNoSupport + return 0, 0, syscall.EWINDOWS } |