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
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2006-07-05 00:10:43 +0400
committerCorinna Vinschen <corinna@vinschen.de>2006-07-05 00:10:43 +0400
commitc2ab308c81a0f9a3a705e743b3123598d5b33243 (patch)
tree4561f90892ab6a7231b4c50e96227824dfeb0e44 /winsup
parent6dbfd8f9baf505c3bf11ef8ba4245a74372c4cab (diff)
* fhandler_socket.cc (fhandler_socket::listen): Allow listening on
unbound INET socket.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog5
-rw-r--r--winsup/cygwin/fhandler_socket.cc20
2 files changed, 22 insertions, 3 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 02324649c..a8a0520f4 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,10 @@
2006-07-04 Corinna Vinschen <corinna@vinschen.de>
+ * fhandler_socket.cc (fhandler_socket::listen): Allow listening on
+ unbound INET socket.
+
+2006-07-04 Corinna Vinschen <corinna@vinschen.de>
+
* fhandler.h (fhandler_socket::wait): Set default timeout to INFINITE.
2006-07-03 Corinna Vinschen <corinna@vinschen.de>
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index e27949600..c3c24d24e 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -804,14 +804,28 @@ int
fhandler_socket::listen (int backlog)
{
int res = ::listen (get_socket (), backlog);
- if (res)
- set_winsock_errno ();
- else
+ if (res && WSAGetLastError () == WSAEINVAL && get_addr_family () == AF_INET)
+ {
+ /* It's perfectly valid to call listen on an unbound INET socket.
+ In this case the socket is automatically bound to an unused
+ port number, listening on all interfaces. On Winsock, listen
+ fails with WSAEINVAL when it's called on an unbound socket.
+ So we have to bind manually here to have POSIX semantics. */
+ struct sockaddr_in sa;
+ sa.sin_family = AF_INET;
+ sa.sin_port = 0;
+ sa.sin_addr.s_addr = INADDR_ANY;
+ if (!::bind (get_socket (), (struct sockaddr *) &sa, sizeof sa))
+ res = ::listen (get_socket (), backlog);
+ }
+ if (!res)
{
if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM)
af_local_set_cred ();
connect_state (connected);
}
+ else
+ set_winsock_errno ();
return res;
}