auto merge of #11845 : xales/rust/libnative, r=alexcrichton

Fixes std::net test error when re-running too quickly.

Suggested by @cmr
This commit is contained in:
bors 2014-01-28 12:01:44 -08:00
commit c6bd05303c
3 changed files with 55 additions and 0 deletions

View File

@ -348,6 +348,17 @@ impl TcpListener {
let (addr, len) = addr_to_sockaddr(addr);
let addrp = &addr as *libc::sockaddr_storage;
let ret = TcpListener { fd: fd };
// On platforms with Berkeley-derived sockets, this allows
// to quickly rebind a socket, without needing to wait for
// the OS to clean up the previous one.
if cfg!(unix) {
match setsockopt(fd, libc::SOL_SOCKET,
libc::SO_REUSEADDR,
1 as libc::c_int) {
Err(n) => { return Err(n); },
Ok(..) => { }
}
}
match libc::bind(fd, addrp as *libc::sockaddr,
len as libc::socklen_t) {
-1 => Err(super::last_error()),

View File

@ -609,4 +609,44 @@ mod test {
c.write([1]);
p.recv();
})
iotest!(fn double_bind() {
let mut called = false;
io_error::cond.trap(|e| {
assert!(e.kind == ConnectionRefused || e.kind == OtherIoError);
called = true;
}).inside(|| {
let addr = next_test_ip4();
let listener = TcpListener::bind(addr).unwrap().listen();
assert!(listener.is_some());
let listener2 = TcpListener::bind(addr).and_then(|l|
l.listen());
assert!(listener2.is_none());
});
assert!(called);
})
iotest!(fn fast_rebind() {
let addr = next_test_ip4();
let (port, chan) = Chan::new();
do spawn {
port.recv();
let stream = TcpStream::connect(addr);
// Close
port.recv();
}
{
let mut acceptor = TcpListener::bind(addr).listen();
chan.send(());
{
let stream = acceptor.accept();
// Close client
chan.send(());
}
// Close listener
}
let listener = TcpListener::bind(addr);
})
}

View File

@ -1547,6 +1547,7 @@ pub mod consts {
pub static SOL_SOCKET: c_int = 0xffff;
pub static SO_KEEPALIVE: c_int = 8;
pub static SO_BROADCAST: c_int = 32;
pub static SO_REUSEADDR: c_int = 4;
}
pub mod extra {
use libc::types::os::arch::c95::c_int;
@ -2266,6 +2267,7 @@ pub mod consts {
pub static SOL_SOCKET: c_int = 1;
pub static SO_KEEPALIVE: c_int = 9;
pub static SO_BROADCAST: c_int = 6;
pub static SO_REUSEADDR: c_int = 2;
}
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "x86_64")]
@ -2707,6 +2709,7 @@ pub mod consts {
pub static SOL_SOCKET: c_int = 0xffff;
pub static SO_KEEPALIVE: c_int = 0x0008;
pub static SO_BROADCAST: c_int = 0x0020;
pub static SO_REUSEADDR: c_int = 0x0004;
}
pub mod extra {
use libc::types::os::arch::c95::c_int;
@ -3083,6 +3086,7 @@ pub mod consts {
pub static SOL_SOCKET: c_int = 0xffff;
pub static SO_KEEPALIVE: c_int = 0x0008;
pub static SO_BROADCAST: c_int = 0x0020;
pub static SO_REUSEADDR: c_int = 0x0004;
}
pub mod extra {
use libc::types::os::arch::c95::c_int;