From c2ab308c81a0f9a3a705e743b3123598d5b33243 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 4 Jul 2006 20:10:43 +0000 Subject: [PATCH] * fhandler_socket.cc (fhandler_socket::listen): Allow listening on unbound INET socket. --- winsup/cygwin/ChangeLog | 5 +++++ winsup/cygwin/fhandler_socket.cc | 20 +++++++++++++++++--- 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,3 +1,8 @@ +2006-07-04 Corinna Vinschen + + * fhandler_socket.cc (fhandler_socket::listen): Allow listening on + unbound INET socket. + 2006-07-04 Corinna Vinschen * fhandler.h (fhandler_socket::wait): Set default timeout to INFINITE. 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; }