mirror of
https://github.com/golang/go
synced 2024-11-24 19:10:15 -07:00
net: add ReadFrom and WriteTo windows version.
Fixes #1275. R=rsc, brainman CC=golang-dev https://golang.org/cl/3136042
This commit is contained in:
parent
1ee4512b98
commit
95c341fc78
@ -243,8 +243,43 @@ func (fd *netFD) Read(p []byte) (n int, err os.Error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err os.Error) {
|
func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err os.Error) {
|
||||||
var r syscall.Sockaddr
|
if fd == nil {
|
||||||
return 0, r, nil
|
return 0, nil, os.EINVAL
|
||||||
|
}
|
||||||
|
if len(p) == 0 {
|
||||||
|
return 0, nil, nil
|
||||||
|
}
|
||||||
|
fd.rio.Lock()
|
||||||
|
defer fd.rio.Unlock()
|
||||||
|
fd.incref()
|
||||||
|
defer fd.decref()
|
||||||
|
if fd.sysfile == nil {
|
||||||
|
return 0, nil, os.EINVAL
|
||||||
|
}
|
||||||
|
// Submit receive request.
|
||||||
|
var pckt ioPacket
|
||||||
|
pckt.c = fd.cr
|
||||||
|
var done uint32
|
||||||
|
flags := uint32(0)
|
||||||
|
var rsa syscall.RawSockaddrAny
|
||||||
|
l := int32(unsafe.Sizeof(rsa))
|
||||||
|
e := syscall.WSARecvFrom(uint32(fd.sysfd), newWSABuf(p), 1, &done, &flags, &rsa, &l, &pckt.o, nil)
|
||||||
|
switch e {
|
||||||
|
case 0:
|
||||||
|
// IO completed immediately, but we need to get our completion message anyway.
|
||||||
|
case syscall.ERROR_IO_PENDING:
|
||||||
|
// IO started, and we have to wait for it's completion.
|
||||||
|
default:
|
||||||
|
return 0, nil, &OpError{"WSARecvFrom", fd.net, fd.laddr, os.Errno(e)}
|
||||||
|
}
|
||||||
|
// Wait for our request to complete.
|
||||||
|
r := <-pckt.c
|
||||||
|
if r.errno != 0 {
|
||||||
|
err = &OpError{"WSARecvFrom", fd.net, fd.laddr, os.Errno(r.errno)}
|
||||||
|
}
|
||||||
|
n = int(r.qty)
|
||||||
|
sa, _ = rsa.Sockaddr()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fd *netFD) Write(p []byte) (n int, err os.Error) {
|
func (fd *netFD) Write(p []byte) (n int, err os.Error) {
|
||||||
@ -281,7 +316,39 @@ func (fd *netFD) Write(p []byte) (n int, err os.Error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fd *netFD) WriteTo(p []byte, sa syscall.Sockaddr) (n int, err os.Error) {
|
func (fd *netFD) WriteTo(p []byte, sa syscall.Sockaddr) (n int, err os.Error) {
|
||||||
return 0, nil
|
if fd == nil {
|
||||||
|
return 0, os.EINVAL
|
||||||
|
}
|
||||||
|
if len(p) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
fd.wio.Lock()
|
||||||
|
defer fd.wio.Unlock()
|
||||||
|
fd.incref()
|
||||||
|
defer fd.decref()
|
||||||
|
if fd.sysfile == nil {
|
||||||
|
return 0, os.EINVAL
|
||||||
|
}
|
||||||
|
// Submit send request.
|
||||||
|
var pckt ioPacket
|
||||||
|
pckt.c = fd.cw
|
||||||
|
var done uint32
|
||||||
|
e := syscall.WSASendto(uint32(fd.sysfd), newWSABuf(p), 1, &done, 0, sa, &pckt.o, nil)
|
||||||
|
switch e {
|
||||||
|
case 0:
|
||||||
|
// IO completed immediately, but we need to get our completion message anyway.
|
||||||
|
case syscall.ERROR_IO_PENDING:
|
||||||
|
// IO started, and we have to wait for it's completion.
|
||||||
|
default:
|
||||||
|
return 0, &OpError{"WSASendTo", fd.net, fd.laddr, os.Errno(e)}
|
||||||
|
}
|
||||||
|
// Wait for our request to complete.
|
||||||
|
r := <-pckt.c
|
||||||
|
if r.errno != 0 {
|
||||||
|
err = &OpError{"WSASendTo", fd.net, fd.laddr, os.Errno(r.errno)}
|
||||||
|
}
|
||||||
|
n = int(r.qty)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os.Error) {
|
func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os.Error) {
|
||||||
|
@ -467,6 +467,8 @@ func Utimes(path string, tv []Timeval) (errno int) {
|
|||||||
//sys GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = wsock32.GetAcceptExSockaddrs
|
//sys GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = wsock32.GetAcceptExSockaddrs
|
||||||
//sys WSARecv(s uint32, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (errno int) [failretval=-1] = ws2_32.WSARecv
|
//sys WSARecv(s uint32, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (errno int) [failretval=-1] = ws2_32.WSARecv
|
||||||
//sys WSASend(s uint32, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (errno int) [failretval=-1] = ws2_32.WSASend
|
//sys WSASend(s uint32, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (errno int) [failretval=-1] = ws2_32.WSASend
|
||||||
|
//sys WSARecvFrom(s uint32, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (errno int) [failretval=-1] = ws2_32.WSARecvFrom
|
||||||
|
//sys WSASendTo(s uint32, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (errno int) [failretval=-1] = ws2_32.WSASendTo
|
||||||
//sys GetHostByName(name string) (h *Hostent, errno int) [failretval=nil] = ws2_32.gethostbyname
|
//sys GetHostByName(name string) (h *Hostent, errno int) [failretval=nil] = ws2_32.gethostbyname
|
||||||
//sys GetServByName(name string, proto string) (s *Servent, errno int) [failretval=nil] = ws2_32.getservbyname
|
//sys GetServByName(name string, proto string) (s *Servent, errno int) [failretval=nil] = ws2_32.getservbyname
|
||||||
//sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
|
//sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
|
||||||
@ -633,6 +635,15 @@ func GetAcceptIOCPSockaddrs(attrs *byte) (lsa, rsa Sockaddr) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WSASendto(s uint32, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (errno int) {
|
||||||
|
rsa, l, err := to.sockaddr()
|
||||||
|
if err != 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
errno = WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(brainman): fix all needed for net
|
// TODO(brainman): fix all needed for net
|
||||||
|
|
||||||
func Accept(fd int) (nfd int, sa Sockaddr, errno int) { return 0, nil, EWINDOWS }
|
func Accept(fd int) (nfd int, sa Sockaddr, errno int) { return 0, nil, EWINDOWS }
|
||||||
|
@ -75,6 +75,8 @@ var (
|
|||||||
procGetAcceptExSockaddrs = getSysProcAddr(modwsock32, "GetAcceptExSockaddrs")
|
procGetAcceptExSockaddrs = getSysProcAddr(modwsock32, "GetAcceptExSockaddrs")
|
||||||
procWSARecv = getSysProcAddr(modws2_32, "WSARecv")
|
procWSARecv = getSysProcAddr(modws2_32, "WSARecv")
|
||||||
procWSASend = getSysProcAddr(modws2_32, "WSASend")
|
procWSASend = getSysProcAddr(modws2_32, "WSASend")
|
||||||
|
procWSARecvFrom = getSysProcAddr(modws2_32, "WSARecvFrom")
|
||||||
|
procWSASendTo = getSysProcAddr(modws2_32, "WSASendTo")
|
||||||
procgethostbyname = getSysProcAddr(modws2_32, "gethostbyname")
|
procgethostbyname = getSysProcAddr(modws2_32, "gethostbyname")
|
||||||
procgetservbyname = getSysProcAddr(modws2_32, "getservbyname")
|
procgetservbyname = getSysProcAddr(modws2_32, "getservbyname")
|
||||||
procntohs = getSysProcAddr(modws2_32, "ntohs")
|
procntohs = getSysProcAddr(modws2_32, "ntohs")
|
||||||
@ -983,6 +985,34 @@ func WSASend(s uint32, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WSARecvFrom(s uint32, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (errno int) {
|
||||||
|
r1, _, e1 := Syscall9(procWSARecvFrom, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
|
||||||
|
if int(r1) == -1 {
|
||||||
|
if e1 != 0 {
|
||||||
|
errno = int(e1)
|
||||||
|
} else {
|
||||||
|
errno = EINVAL
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errno = 0
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func WSASendTo(s uint32, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (errno int) {
|
||||||
|
r1, _, e1 := Syscall9(procWSASendTo, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
|
||||||
|
if int(r1) == -1 {
|
||||||
|
if e1 != 0 {
|
||||||
|
errno = int(e1)
|
||||||
|
} else {
|
||||||
|
errno = EINVAL
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errno = 0
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetHostByName(name string) (h *Hostent, errno int) {
|
func GetHostByName(name string) (h *Hostent, errno int) {
|
||||||
r0, _, e1 := Syscall(procgethostbyname, uintptr(unsafe.Pointer(StringBytePtr(name))), 0, 0)
|
r0, _, e1 := Syscall(procgethostbyname, uintptr(unsafe.Pointer(StringBytePtr(name))), 0, 0)
|
||||||
h = (*Hostent)(unsafe.Pointer(r0))
|
h = (*Hostent)(unsafe.Pointer(r0))
|
||||||
|
Loading…
Reference in New Issue
Block a user