Zebediah Figura : server: Introduce IOCTL_AFD_WINE_SHUTDOWN.

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


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

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

server: Introduce IOCTL_AFD_WINE_SHUTDOWN.

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

---

 include/wine/afd.h |  1 +
 server/sock.c      | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/include/wine/afd.h b/include/wine/afd.h
index b085981b6c0..30429b02324 100644
--- a/include/wine/afd.h
+++ b/include/wine/afd.h
@@ -37,6 +37,7 @@ struct afd_listen_params
 #define IOCTL_AFD_WINE_ACCEPT               CTL_CODE(FILE_DEVICE_NETWORK, 201, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define IOCTL_AFD_WINE_ACCEPT_INTO          CTL_CODE(FILE_DEVICE_NETWORK, 202, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define IOCTL_AFD_WINE_CONNECT              CTL_CODE(FILE_DEVICE_NETWORK, 203, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_AFD_WINE_SHUTDOWN             CTL_CODE(FILE_DEVICE_NETWORK, 204, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
 #define IOCTL_AFD_WINE_ADDRESS_LIST_CHANGE  CTL_CODE(FILE_DEVICE_NETWORK, 323, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
diff --git a/server/sock.c b/server/sock.c
index 9896810def1..b523e8db780 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -135,6 +135,7 @@ struct sock
     unsigned int        reported_events;
     unsigned int        flags;       /* socket flags */
     int                 polling;     /* is socket being polled? */
+    int                 wr_shutdown_pending; /* is a write shutdown pending? */
     unsigned short      proto;       /* socket protocol */
     unsigned short      type;        /* socket type */
     unsigned short      family;      /* socket family */
@@ -912,6 +913,9 @@ static void sock_reselect_async( struct fd *fd, struct async_queue *queue )
 {
     struct sock *sock = get_fd_user( fd );
 
+    if (sock->wr_shutdown_pending && list_empty( &sock->write_q.queue ))
+        shutdown( get_unix_fd( sock->fd ), SHUT_WR );
+
     /* Don't reselect the ifchange queue; we always ask for POLLIN.
      * Don't reselect an uninitialized socket; we can't call set_fd_events() on
      * a pseudo-fd. */
@@ -983,6 +987,7 @@ static struct sock *create_socket(void)
     sock->pending_events = 0;
     sock->reported_events = 0;
     sock->polling = 0;
+    sock->wr_shutdown_pending = 0;
     sock->flags   = 0;
     sock->proto   = 0;
     sock->type    = 0;
@@ -1638,6 +1643,55 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
         return 1;
     }
 
+    case IOCTL_AFD_WINE_SHUTDOWN:
+    {
+        unsigned int how;
+
+        if (get_req_data_size() < sizeof(int))
+        {
+            set_error( STATUS_BUFFER_TOO_SMALL );
+            return 0;
+        }
+        how = *(int *)get_req_data();
+
+        if (how > SD_BOTH)
+        {
+            set_error( STATUS_INVALID_PARAMETER );
+            return 0;
+        }
+
+        if (sock->type == WS_SOCK_STREAM && !(sock->state & FD_WINE_CONNECTED))
+        {
+            set_error( STATUS_INVALID_CONNECTION );
+            return 0;
+        }
+
+        if (how != SD_SEND)
+        {
+            sock->state &= ~FD_READ;
+        }
+        if (how != SD_RECEIVE)
+        {
+            sock->state &= ~FD_WRITE;
+            if (list_empty( &sock->write_q.queue ))
+                shutdown( unix_fd, SHUT_WR );
+            else
+                sock->wr_shutdown_pending = 1;
+        }
+
+        if (how == SD_BOTH)
+        {
+            if (sock->event) release_object( sock->event );
+            sock->event = NULL;
+            sock->window = 0;
+            sock->mask = 0;
+            sock->state |= FD_WINE_NONBLOCKING;
+        }
+
+        sock_reselect( sock );
+        return 1;
+    }
+
     case IOCTL_AFD_WINE_ADDRESS_LIST_CHANGE:
         if ((sock->state & FD_WINE_NONBLOCKING) && async_is_blocking( async ))
         {




More information about the wine-cvs mailing list