diff options
author | Ken Brown <kbrown@cornell.edu> | 2021-04-24 01:17:57 +0300 |
---|---|---|
committer | Ken Brown <kbrown@cornell.edu> | 2021-04-27 17:01:45 +0300 |
commit | 3b0ba6535218631b1ab467cd29d36b1eae4a0af6 (patch) | |
tree | 88b79fe3fbb81213983746e755fc514f145bfde3 /winsup/cygwin/fhandler_socket_inet.cc | |
parent | 2be07f75548a9111ebf9b5cb4bb1040c3dc4f4f0 (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.cc | 21 |
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) |