public inbox for cygwin-patches@cygwin.com
 help / color / mirror / Atom feed
From: Ken Brown <kbrown@cornell.edu>
To: cygwin-patches@cygwin.com
Subject: [PATCH] Cygwin: connect: set connect state for DGRAM sockets
Date: Fri, 23 Apr 2021 14:51:41 -0400	[thread overview]
Message-ID: <20210423185141.7687-1-kbrown@cornell.edu> (raw)

When connect is called on a DGRAM socket, the call to Winsock's
connect can immediately return successfully rather than failing with
WSAEWOULDBLOCK.  Set the connect state to "connected" in this case.

Previously the connect state remained "connect_pending" after the
successful connection.
---
 winsup/cygwin/fhandler_socket_inet.cc  | 19 +++++++++++--------
 winsup/cygwin/fhandler_socket_local.cc | 19 +++++++++++--------
 2 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/winsup/cygwin/fhandler_socket_inet.cc b/winsup/cygwin/fhandler_socket_inet.cc
index 4ecb31a27..f6bb8c503 100644
--- a/winsup/cygwin/fhandler_socket_inet.cc
+++ b/winsup/cygwin/fhandler_socket_inet.cc
@@ -785,11 +785,13 @@ fhandler_socket_inet::connect (const struct sockaddr *name, int namelen)
   if (get_inet_addr_inet (name, namelen, &sst, &namelen) == SOCKET_ERROR)
     return SOCKET_ERROR;
 
-  /* Initialize connect state to "connect_pending".  State is ultimately set
-     to "connected" or "connect_failed" in wait_for_events when the FD_CONNECT
-     event occurs.  Note that the underlying OS sockets are always non-blocking
-     and a successfully initiated non-blocking Winsock connect always returns
-     WSAEWOULDBLOCK.  Thus it's safe to rely on event handling.
+  /* Initialize connect state to "connect_pending".  In the SOCK_STREAM
+     case, the state is ultimately set to "connected" or "connect_failed" in
+     wait_for_events when the FD_CONNECT event occurs.  Note that the
+     underlying OS sockets are always non-blocking in this case and a
+     successfully initiated non-blocking Winsock connect always returns
+     WSAEWOULDBLOCK.  Thus it's safe to rely on event handling.  For DGRAM
+     sockets, however, connect can return immediately.
 
      Check for either unconnected or connect_failed since in both cases it's
      allowed to retry connecting the socket.  It's also ok (albeit ugly) to
@@ -801,7 +803,9 @@ fhandler_socket_inet::connect (const struct sockaddr *name, int namelen)
     connect_state (connect_pending);
 
   int res = ::connect (get_socket (), (struct sockaddr *) &sst, namelen);
-  if (!is_nonblocking ()
+  if (!res)
+    connect_state (connected);
+  else if (!is_nonblocking ()
       && res == SOCKET_ERROR
       && WSAGetLastError () == WSAEWOULDBLOCK)
     res = wait_for_events (FD_CONNECT | FD_CLOSE, 0);
@@ -824,8 +828,7 @@ fhandler_socket_inet::connect (const struct sockaddr *name, int namelen)
 	 Convert to POSIX/Linux compliant EISCONN. */
       else if (err == WSAEINVAL && connect_state () == listener)
 	WSASetLastError (WSAEISCONN);
-      /* Any other error except WSAEALREADY during connect_pending means the
-         connect failed. */
+      /* Any other error except WSAEALREADY means the connect failed. */
       else if (connect_state () == connect_pending && err != WSAEALREADY)
 	connect_state (connect_failed);
       set_winsock_errno ();
diff --git a/winsup/cygwin/fhandler_socket_local.cc b/winsup/cygwin/fhandler_socket_local.cc
index ad7dd0a98..1c8d48b58 100644
--- a/winsup/cygwin/fhandler_socket_local.cc
+++ b/winsup/cygwin/fhandler_socket_local.cc
@@ -914,11 +914,13 @@ fhandler_socket_local::connect (const struct sockaddr *name, int namelen)
   if (get_socket_type () == SOCK_STREAM)
     af_local_set_cred ();
 
-  /* Initialize connect state to "connect_pending".  State is ultimately set
-     to "connected" or "connect_failed" in wait_for_events when the FD_CONNECT
-     event occurs.  Note that the underlying OS sockets are always non-blocking
-     and a successfully initiated non-blocking Winsock connect always returns
-     WSAEWOULDBLOCK.  Thus it's safe to rely on event handling.
+  /* Initialize connect state to "connect_pending".  In the SOCK_STREAM
+     case, the state is ultimately set to "connected" or "connect_failed" in
+     wait_for_events when the FD_CONNECT event occurs.  Note that the
+     underlying OS sockets are always non-blocking in this case and a
+     successfully initiated non-blocking Winsock connect always returns
+     WSAEWOULDBLOCK.  Thus it's safe to rely on event handling.  For DGRAM
+     sockets, however, connect can return immediately.
 
      Check for either unconnected or connect_failed since in both cases it's
      allowed to retry connecting the socket.  It's also ok (albeit ugly) to
@@ -930,7 +932,9 @@ fhandler_socket_local::connect (const struct sockaddr *name, int namelen)
     connect_state (connect_pending);
 
   int res = ::connect (get_socket (), (struct sockaddr *) &sst, namelen);
-  if (!is_nonblocking ()
+  if (!res)
+    connect_state (connected);
+  else if (!is_nonblocking ()
       && res == SOCKET_ERROR
       && WSAGetLastError () == WSAEWOULDBLOCK)
     res = wait_for_events (FD_CONNECT | FD_CLOSE, 0);
@@ -953,8 +957,7 @@ fhandler_socket_local::connect (const struct sockaddr *name, int namelen)
 	 Convert to POSIX/Linux compliant EISCONN. */
       else if (err == WSAEINVAL && connect_state () == listener)
 	WSASetLastError (WSAEISCONN);
-      /* Any other error except WSAEALREADY during connect_pending means the
-         connect failed. */
+      /* Any other error except WSAEALREADY means the connect failed. */
       else if (connect_state () == connect_pending && err != WSAEALREADY)
 	connect_state (connect_failed);
       set_winsock_errno ();
-- 
2.31.0


             reply	other threads:[~2021-04-23 18:52 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-23 18:51 Ken Brown [this message]
2021-04-26  9:28 ` Corinna Vinschen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210423185141.7687-1-kbrown@cornell.edu \
    --to=kbrown@cornell.edu \
    --cc=cygwin-patches@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).