]> sourceware.org Git - newlib-cygwin.git/commitdiff
* autoload.cc (WSARecv): Define.
authorCorinna Vinschen <corinna@vinschen.de>
Tue, 22 Sep 2009 14:27:57 +0000 (14:27 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Tue, 22 Sep 2009 14:27:57 +0000 (14:27 +0000)
* fhandler_socket.cc (fhandler_socket::recv_internal): Call WSARecv
instead of WSARecvFrom if no name parameter is given.  Explain why.

winsup/cygwin/ChangeLog
winsup/cygwin/autoload.cc
winsup/cygwin/fhandler_socket.cc

index 9752abe5e95d7a948a032cc9b81200e0304e2b82..b09bf6fa7a02048755f34d112cc3e5d8e50c113b 100644 (file)
@@ -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>
 
        * syscalls.cc (faccessat): Fix typo, reject bad flags.
index afe6028a58c831e59bf8e101fff5bab9e9405ecf..94289130348a318dcb371c5917c569d4d3db5c13 100644 (file)
@@ -391,6 +391,7 @@ LoadDLLfunc (WSAEnumNetworkEvents, 12, ws2_32)
 LoadDLLfunc (WSAEventSelect, 12, ws2_32)
 LoadDLLfunc (WSAGetLastError, 0, ws2_32)
 LoadDLLfunc (WSAIoctl, 36, ws2_32)
+LoadDLLfunc (WSARecv, 28, ws2_32)
 LoadDLLfunc (WSARecvFrom, 36, ws2_32)
 LoadDLLfunc (WSASendMsg, 24, ws2_32)
 LoadDLLfunc (WSASendTo, 36, ws2_32)
index 52d03ed078d985057e6a0fa074fccdd6f253a6b4..3e218347da62b9cad41106c602dcee5b1349299a 100644 (file)
@@ -1379,14 +1379,30 @@ fhandler_socket::recv_internal (LPWSAMSG wsamsg)
     {
       if (use_recvmsg)
        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
        res = WSARecvFrom (get_socket (), wsabuf, wsacnt, &wret,
-                          &wsamsg->dwFlags, wsamsg->name,
-                          /* 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,
+                          &wsamsg->dwFlags, wsamsg->name, &wsamsg->namelen,
                           NULL, NULL);
       if (!res)
        {
This page took 0.037033 seconds and 5 git commands to generate.