Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Brown <kbrown@cornell.edu>2021-04-24 01:17:57 +0300
committerKen Brown <kbrown@cornell.edu>2021-04-27 17:01:45 +0300
commit3b0ba6535218631b1ab467cd29d36b1eae4a0af6 (patch)
tree88b79fe3fbb81213983746e755fc514f145bfde3 /winsup/cygwin/fhandler_socket_inet.cc
parent2be07f75548a9111ebf9b5cb4bb1040c3dc4f4f0 (diff)
Cygwin: connect: implement resetting a connected DGRAM socket
Following POSIX and Linux, allow a connected DGRAM socket's connection to be reset (so that the socket becomes unconnected). This is done by calling connect and specifing an address whose family is AF_UNSPEC.
Diffstat (limited to 'winsup/cygwin/fhandler_socket_inet.cc')
-rw-r--r--winsup/cygwin/fhandler_socket_inet.cc21
1 files changed, 19 insertions, 2 deletions
diff --git a/winsup/cygwin/fhandler_socket_inet.cc b/winsup/cygwin/fhandler_socket_inet.cc
index f6bb8c503..30eab4099 100644
--- a/winsup/cygwin/fhandler_socket_inet.cc
+++ b/winsup/cygwin/fhandler_socket_inet.cc
@@ -781,8 +781,20 @@ int
fhandler_socket_inet::connect (const struct sockaddr *name, int namelen)
{
struct sockaddr_storage sst;
+ bool reset = (name->sa_family == AF_UNSPEC
+ && get_socket_type () == SOCK_DGRAM);
- if (get_inet_addr_inet (name, namelen, &sst, &namelen) == SOCKET_ERROR)
+ if (reset)
+ {
+ if (connect_state () == unconnected)
+ return 0;
+ /* To reset a connected DGRAM socket, call Winsock's connect
+ function with the address member of the sockaddr structure
+ filled with zeroes. */
+ memset (&sst, 0, sizeof sst);
+ sst.ss_family = get_addr_family ();
+ }
+ else if (get_inet_addr_inet (name, namelen, &sst, &namelen) == SOCKET_ERROR)
return SOCKET_ERROR;
/* Initialize connect state to "connect_pending". In the SOCK_STREAM
@@ -804,7 +816,12 @@ fhandler_socket_inet::connect (const struct sockaddr *name, int namelen)
int res = ::connect (get_socket (), (struct sockaddr *) &sst, namelen);
if (!res)
- connect_state (connected);
+ {
+ if (reset)
+ connect_state (unconnected);
+ else
+ connect_state (connected);
+ }
else if (!is_nonblocking ()
&& res == SOCKET_ERROR
&& WSAGetLastError () == WSAEWOULDBLOCK)