Zebediah Figura : ws2_32: Do not use SHUT_RD.

Alexandre Julliard julliard at winehq.org
Wed May 19 14:55:12 CDT 2021


Module: wine
Branch: master
Commit: 416072a84c5bea7f619c3fa1396274396d44236b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=416072a84c5bea7f619c3fa1396274396d44236b

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Tue May 18 22:35:48 2021 -0500

ws2_32: Do not use SHUT_RD.

Win32 SD_RECEIVE has the following effects on a TCP or UDP socket:

* further calls to recv() et al. fail with ESHUTDOWN. However, Linux and Mac
  instead return 0.

* currently pending calls to recv() are not affected. However, Linux and Mac
  cause them to return 0.

* calls to WSAPoll() are unaffected. However, Linux and Mac instead signal
  both POLLHUP and POLLIN.

* for TCP connections, further data sent by the peer causes the connection to be
  reset. Mac and BSD will silently drop data, and Linux simply queues it
  forever.

In short, SHUT_RD does nothing that we want it to do on Linux or Mac (and
probably also BSD, though I am unable to test this).

Most of this impedance mismatch can be worked around in Wine, except for
WSAPoll(). Since poll() will always return POLLHUP, we can't safely ask for
POLLOUT, which we may need to do. Hence, since we aren't getting any benefit
from SHUT_RD, don't use it.

Note that this doesn't actually fix any tests, since we have some rather bizarre
logic to defer shutdown anyway (for an asynchronous socket, we don't call
shutdown(SHUT_RD) until the peer sends data; this is probably an unintended bug,
but "fixing" it ends up causing test failures, which is the main impetus for
this patch.)

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ws2_32/socket.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 889f0327baf..aad92d5d4df 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -2290,7 +2290,7 @@ static NTSTATUS WS2_async_shutdown( void *user, IO_STATUS_BLOCK *iosb, NTSTATUS
 
         switch ( wsa->type )
         {
-        case ASYNC_TYPE_READ:   err = shutdown( fd, 0 );  break;
+        case ASYNC_TYPE_READ:   break;
         case ASYNC_TYPE_WRITE:  err = shutdown( fd, 1 );  break;
         }
         status = err ? wsaErrStatus() : STATUS_SUCCESS;
@@ -5550,7 +5550,7 @@ int WINAPI WS_shutdown(SOCKET s, int how)
     }
     else /* non-overlapped mode */
     {
-        if ( shutdown( fd, how ) )
+        if (how != SD_RECEIVE && shutdown( fd, SHUT_WR ))
         {
             err = wsaErrno();
             goto error;




More information about the wine-cvs mailing list