* autoload.cc (WSARecv): Define.
* fhandler_socket.cc (fhandler_socket::recv_internal): Call WSARecv instead of WSARecvFrom if no name parameter is given. Explain why.
This commit is contained in:
parent
74a67d01a5
commit
5e8d7527af
|
@ -1,3 +1,9 @@
|
||||||
|
2009-09-22 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* autoload.cc (WSARecv): Define.
|
||||||
|
* fhandler_socket.cc (fhandler_socket::recv_internal): Call WSARecv
|
||||||
|
instead of WSARecvFrom if no name parameter is given. Explain why.
|
||||||
|
|
||||||
2009-09-22 Eric Blake <ebb9@byu.net>
|
2009-09-22 Eric Blake <ebb9@byu.net>
|
||||||
|
|
||||||
* syscalls.cc (faccessat): Fix typo, reject bad flags.
|
* syscalls.cc (faccessat): Fix typo, reject bad flags.
|
||||||
|
|
|
@ -391,6 +391,7 @@ LoadDLLfunc (WSAEnumNetworkEvents, 12, ws2_32)
|
||||||
LoadDLLfunc (WSAEventSelect, 12, ws2_32)
|
LoadDLLfunc (WSAEventSelect, 12, ws2_32)
|
||||||
LoadDLLfunc (WSAGetLastError, 0, ws2_32)
|
LoadDLLfunc (WSAGetLastError, 0, ws2_32)
|
||||||
LoadDLLfunc (WSAIoctl, 36, ws2_32)
|
LoadDLLfunc (WSAIoctl, 36, ws2_32)
|
||||||
|
LoadDLLfunc (WSARecv, 28, ws2_32)
|
||||||
LoadDLLfunc (WSARecvFrom, 36, ws2_32)
|
LoadDLLfunc (WSARecvFrom, 36, ws2_32)
|
||||||
LoadDLLfunc (WSASendMsg, 24, ws2_32)
|
LoadDLLfunc (WSASendMsg, 24, ws2_32)
|
||||||
LoadDLLfunc (WSASendTo, 36, ws2_32)
|
LoadDLLfunc (WSASendTo, 36, ws2_32)
|
||||||
|
|
|
@ -1379,14 +1379,30 @@ fhandler_socket::recv_internal (LPWSAMSG wsamsg)
|
||||||
{
|
{
|
||||||
if (use_recvmsg)
|
if (use_recvmsg)
|
||||||
res = WSARecvMsg (get_socket (), wsamsg, &wret, NULL, NULL);
|
res = WSARecvMsg (get_socket (), wsamsg, &wret, NULL, NULL);
|
||||||
|
/* This is working around a really weird problem in WinSock.
|
||||||
|
|
||||||
|
Assume you create a socket, fork the process (thus duplicating
|
||||||
|
the socket), connect the socket in the child, then call recv
|
||||||
|
on the original socket handle in the parent process.
|
||||||
|
In this scenario, calls to WinSock's recvfrom and WSARecvFrom
|
||||||
|
in the parent will fail with WSAEINVAL, regardless whether both
|
||||||
|
address parameters, name and namelen, are NULL or point to valid
|
||||||
|
storage. However, calls to recv and WSARecv succeed as expected.
|
||||||
|
Per MSDN, WSAEINVAL in the context of recv means "The socket has not
|
||||||
|
been bound". It is as if the recvfrom functions test if the socket
|
||||||
|
is bound locally, but in the parent process, WinSock doesn't know
|
||||||
|
about that and fails, while the same test is omitted in the recv
|
||||||
|
functions.
|
||||||
|
|
||||||
|
This also covers another weird case: Winsock returns WSAEFAULT if
|
||||||
|
namelen is a valid pointer while name is NULL. Both parameters are
|
||||||
|
ignored for TCP sockets, so this only occurs when using UDP socket. */
|
||||||
|
else if (!wsamsg->name)
|
||||||
|
res = WSARecv (get_socket (), wsabuf, wsacnt, &wret, &wsamsg->dwFlags,
|
||||||
|
NULL, NULL);
|
||||||
else
|
else
|
||||||
res = WSARecvFrom (get_socket (), wsabuf, wsacnt, &wret,
|
res = WSARecvFrom (get_socket (), wsabuf, wsacnt, &wret,
|
||||||
&wsamsg->dwFlags, wsamsg->name,
|
&wsamsg->dwFlags, wsamsg->name, &wsamsg->namelen,
|
||||||
/* Winsock returns WSAEFAULT if namelen is a valid
|
|
||||||
pointer while name is NULL. Both parameters are
|
|
||||||
ignored for TCP sockets, so this only occurs when
|
|
||||||
using UDP socket. */
|
|
||||||
wsamsg->name ? &wsamsg->namelen : NULL,
|
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue