pub struct UnixListener {
inner: Inner,
+ path: CString,
}
impl UnixListener {
pub fn bind(addr: &CString) -> IoResult<UnixListener> {
- bind(addr, libc::SOCK_STREAM).map(|fd| UnixListener { inner: fd })
+ bind(addr, libc::SOCK_STREAM).map(|fd| {
+ UnixListener { inner: fd, path: addr.clone() }
+ })
}
fn fd(&self) -> fd_t { self.inner.fd }
self.native_accept().map(|s| ~s as ~rtio::RtioPipe:Send)
}
}
+
+impl Drop for UnixListener {
+ fn drop(&mut self) {
+ // Unlink the path to the socket to ensure that it doesn't linger. We're
+ // careful to unlink the path before we close the file descriptor to
+ // prevent races where we unlink someone else's path.
+ unsafe {
+ let _ = libc::unlink(self.path.with_ref(|p| p));
+ }
+ }
+}
rx.recv();
})
+
+ iotest!(fn drop_removes_listener_path() {
+ let path = next_test_unix();
+ let l = UnixListener::bind(&path).unwrap();
+ assert!(path.exists());
+ drop(l);
+ assert!(!path.exists());
+ } #[cfg(not(windows))])
+
+ iotest!(fn drop_removes_acceptor_path() {
+ let path = next_test_unix();
+ let l = UnixListener::bind(&path).unwrap();
+ assert!(path.exists());
+ drop(l.listen().unwrap());
+ assert!(!path.exists());
+ } #[cfg(not(windows))])
}