summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fhandler_socket.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2006-01-29 12:23:44 +0000
committerCorinna Vinschen <corinna@vinschen.de>2006-01-29 12:23:44 +0000
commit5369605f4f7a8275f47e695856d42dc39bcbd3e3 (patch)
treeb09aa426d96850b857d08f5ba13069c60e473101 /winsup/cygwin/fhandler_socket.cc
parent74d3f96faa7a547c4b9ebcfab3d3a850b0389202 (diff)
downloadcygnal-5369605f4f7a8275f47e695856d42dc39bcbd3e3.tar.gz
cygnal-5369605f4f7a8275f47e695856d42dc39bcbd3e3.tar.bz2
cygnal-5369605f4f7a8275f47e695856d42dc39bcbd3e3.zip
* fhandler.h (class fhandler_socket): Add saw_reuseaddr status flag.
* fhandler_socket.cc (fhandler_socket::bind): Set socket to SO_EXCLUSIVEADDRUSE if application didn't explicitely set SO_REUSEADDR socket option, on systems supporting SO_EXCLUSIVEADDRUSE. * net.cc (cygwin_setsockopt): Set fhandler's saw_reuseaddr status flag if SO_REUSEADDR socket option has been successsfully set. * wincap.h (wincaps::has_exclusiveaddruse): New element. * wincap.cc: Implement above element throughout.
Diffstat (limited to 'winsup/cygwin/fhandler_socket.cc')
-rw-r--r--winsup/cygwin/fhandler_socket.cc29
1 files changed, 26 insertions, 3 deletions
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 2405471fe..b885b97db 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -661,10 +661,33 @@ fhandler_socket::bind (const struct sockaddr *name, int namelen)
}
#undef un_addr
}
- else if (::bind (get_socket (), name, namelen))
- set_winsock_errno ();
else
- res = 0;
+ {
+ /* If the application didn't explicitely call setsockopt (SO_REUSEADDR),
+ enforce exclusive local address use using the SO_EXCLUSIVEADDRUSE
+ socket option, to emulate POSIX socket behaviour more closely.
+
+ KB 870562: Note that this option is only available since NT4 SP4.
+ Also note that a bug in Win2K SP1-3 and XP up to SP1 only enables
+ this option for users in the local administrators group. */
+ if (wincap.has_exclusiveaddruse ())
+ {
+ if (!saw_reuseaddr ())
+ {
+ int on = 1;
+ int ret = ::setsockopt (get_socket (), SOL_SOCKET,
+ ~(SO_REUSEADDR),
+ (const char *) &on, sizeof on);
+ debug_printf ("%d = setsockopt (SO_EXCLUSIVEADDRUSE), %E", ret);
+ }
+ else
+ debug_printf ("SO_REUSEADDR set");
+ }
+ if (::bind (get_socket (), name, namelen))
+ set_winsock_errno ();
+ else
+ res = 0;
+ }
out:
return res;