1 use super::{sockaddr_un, SocketAddr, UnixStream}; 2 use crate::std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; 3 use crate::std::path::Path; 4 use crate::std::sys::cvt; 5 use crate::std::sys::net::Socket; 6 use crate::std::sys_common::{AsInner, FromInner, IntoInner}; 7 use crate::std::{fmt, io, mem}; 8 use dlibc; 9 10 /// A structure representing a Unix domain socket server. 11 /// 12 /// # Examples 13 /// 14 /// ```no_run 15 /// use std::thread; 16 /// use std::os::unix::net::{UnixStream, UnixListener}; 17 /// 18 /// fn handle_client(stream: UnixStream) { 19 /// // ... 20 /// } 21 /// 22 /// fn main() -> std::io::Result<()> { 23 /// let listener = UnixListener::bind("/path/to/the/socket")?; 24 /// 25 /// // accept connections and process them, spawning a new thread for each one 26 /// for stream in listener.incoming() { 27 /// match stream { 28 /// Ok(stream) => { 29 /// /* connection succeeded */ 30 /// thread::spawn(|| handle_client(stream)); 31 /// } 32 /// Err(err) => { 33 /// /* connection failed */ 34 /// break; 35 /// } 36 /// } 37 /// } 38 /// Ok(()) 39 /// } 40 /// ``` 41 pub struct UnixListener(Socket); 42 43 impl fmt::Debug for UnixListener { 44 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 45 let mut builder = fmt.debug_struct("UnixListener"); 46 builder.field("fd", self.0.as_inner()); 47 if let Ok(addr) = self.local_addr() { 48 builder.field("local", &addr); 49 } 50 builder.finish() 51 } 52 } 53 54 impl UnixListener { 55 /// Creates a new `UnixListener` bound to the specified socket. 56 /// 57 /// # Examples 58 /// 59 /// ```no_run 60 /// use std::os::unix::net::UnixListener; 61 /// 62 /// let listener = match UnixListener::bind("/path/to/the/socket") { 63 /// Ok(sock) => sock, 64 /// Err(e) => { 65 /// println!("Couldn't connect: {e:?}"); 66 /// return 67 /// } 68 /// }; 69 /// ``` 70 pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> { 71 unsafe { 72 let inner = Socket::new_raw(dlibc::AF_UNIX, dlibc::SOCK_STREAM)?; 73 let (addr, len) = sockaddr_un(path.as_ref())?; 74 const backlog: dlibc::c_int = if cfg!(any(target_os = "linux", target_os = "freebsd")) { 75 -1 76 } else { 77 128 78 }; 79 80 cvt(dlibc::bind( 81 inner.as_inner().as_raw_fd(), 82 &addr as *const _ as *const _, 83 len as _, 84 ))?; 85 cvt(dlibc::listen(inner.as_inner().as_raw_fd(), backlog))?; 86 87 Ok(UnixListener(inner)) 88 } 89 } 90 91 /// Creates a new `UnixListener` bound to the specified [`socket address`]. 92 /// 93 /// [`socket address`]: crate::std::os::unix::net::SocketAddr 94 /// 95 /// # Examples 96 /// 97 /// ```no_run 98 /// use std::os::unix::net::{UnixListener}; 99 /// 100 /// fn main() -> std::io::Result<()> { 101 /// let listener1 = UnixListener::bind("path/to/socket")?; 102 /// let addr = listener1.local_addr()?; 103 /// 104 /// let listener2 = match UnixListener::bind_addr(&addr) { 105 /// Ok(sock) => sock, 106 /// Err(err) => { 107 /// println!("Couldn't bind: {err:?}"); 108 /// return Err(err); 109 /// } 110 /// }; 111 /// Ok(()) 112 /// } 113 /// ``` 114 pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result<UnixListener> { 115 unsafe { 116 let inner = Socket::new_raw(dlibc::AF_UNIX, dlibc::SOCK_STREAM)?; 117 #[cfg(target_os = "linux")] 118 const backlog: dlibc::c_int = -1; 119 #[cfg(not(target_os = "linux"))] 120 const backlog: dlibc::c_int = 128; 121 cvt(dlibc::bind( 122 inner.as_raw_fd(), 123 &socket_addr.addr as *const _ as *const _, 124 socket_addr.len as _, 125 ))?; 126 cvt(dlibc::listen(inner.as_raw_fd(), backlog))?; 127 Ok(UnixListener(inner)) 128 } 129 } 130 131 /// Accepts a new incoming connection to this listener. 132 /// 133 /// This function will block the calling thread until a new Unix connection 134 /// is established. When established, the corresponding [`UnixStream`] and 135 /// the remote peer's address will be returned. 136 /// 137 /// [`UnixStream`]: crate::std::os::unix::net::UnixStream 138 /// 139 /// # Examples 140 /// 141 /// ```no_run 142 /// use std::os::unix::net::UnixListener; 143 /// 144 /// fn main() -> std::io::Result<()> { 145 /// let listener = UnixListener::bind("/path/to/the/socket")?; 146 /// 147 /// match listener.accept() { 148 /// Ok((socket, addr)) => println!("Got a client: {addr:?}"), 149 /// Err(e) => println!("accept function failed: {e:?}"), 150 /// } 151 /// Ok(()) 152 /// } 153 /// ``` 154 pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> { 155 let mut storage: dlibc::sockaddr_un = unsafe { mem::zeroed() }; 156 let mut len = mem::size_of_val(&storage) as dlibc::socklen_t; 157 let sock = self.0.accept(&mut storage as *mut _ as *mut _, &mut len)?; 158 let addr = SocketAddr::from_parts(storage, len)?; 159 Ok((UnixStream(sock), addr)) 160 } 161 162 /// Creates a new independently owned handle to the underlying socket. 163 /// 164 /// The returned `UnixListener` is a reference to the same socket that this 165 /// object references. Both handles can be used to accept incoming 166 /// connections and options set on one listener will affect the other. 167 /// 168 /// # Examples 169 /// 170 /// ```no_run 171 /// use std::os::unix::net::UnixListener; 172 /// 173 /// fn main() -> std::io::Result<()> { 174 /// let listener = UnixListener::bind("/path/to/the/socket")?; 175 /// let listener_copy = listener.try_clone().expect("try_clone failed"); 176 /// Ok(()) 177 /// } 178 /// ``` 179 pub fn try_clone(&self) -> io::Result<UnixListener> { 180 self.0.duplicate().map(UnixListener) 181 } 182 183 /// Returns the local socket address of this listener. 184 /// 185 /// # Examples 186 /// 187 /// ```no_run 188 /// use std::os::unix::net::UnixListener; 189 /// 190 /// fn main() -> std::io::Result<()> { 191 /// let listener = UnixListener::bind("/path/to/the/socket")?; 192 /// let addr = listener.local_addr().expect("Couldn't get local address"); 193 /// Ok(()) 194 /// } 195 /// ``` 196 pub fn local_addr(&self) -> io::Result<SocketAddr> { 197 SocketAddr::new(|addr, len| unsafe { dlibc::getsockname(self.as_raw_fd(), addr, len) }) 198 } 199 200 /// Moves the socket into or out of nonblocking mode. 201 /// 202 /// This will result in the `accept` operation becoming nonblocking, 203 /// i.e., immediately returning from their calls. If the IO operation is 204 /// successful, `Ok` is returned and no further action is required. If the 205 /// IO operation could not be completed and needs to be retried, an error 206 /// with kind [`io::ErrorKind::WouldBlock`] is returned. 207 /// 208 /// # Examples 209 /// 210 /// ```no_run 211 /// use std::os::unix::net::UnixListener; 212 /// 213 /// fn main() -> std::io::Result<()> { 214 /// let listener = UnixListener::bind("/path/to/the/socket")?; 215 /// listener.set_nonblocking(true).expect("Couldn't set non blocking"); 216 /// Ok(()) 217 /// } 218 /// ``` 219 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { 220 self.0.set_nonblocking(nonblocking) 221 } 222 223 /// Returns the value of the `SO_ERROR` option. 224 /// 225 /// # Examples 226 /// 227 /// ```no_run 228 /// use std::os::unix::net::UnixListener; 229 /// 230 /// fn main() -> std::io::Result<()> { 231 /// let listener = UnixListener::bind("/tmp/sock")?; 232 /// 233 /// if let Ok(Some(err)) = listener.take_error() { 234 /// println!("Got error: {err:?}"); 235 /// } 236 /// Ok(()) 237 /// } 238 /// ``` 239 /// 240 /// # Platform specific 241 /// On Redox this always returns `None`. 242 pub fn take_error(&self) -> io::Result<Option<io::Error>> { 243 self.0.take_error() 244 } 245 246 /// Returns an iterator over incoming connections. 247 /// 248 /// The iterator will never return [`None`] and will also not yield the 249 /// peer's [`SocketAddr`] structure. 250 /// 251 /// # Examples 252 /// 253 /// ```no_run 254 /// use std::thread; 255 /// use std::os::unix::net::{UnixStream, UnixListener}; 256 /// 257 /// fn handle_client(stream: UnixStream) { 258 /// // ... 259 /// } 260 /// 261 /// fn main() -> std::io::Result<()> { 262 /// let listener = UnixListener::bind("/path/to/the/socket")?; 263 /// 264 /// for stream in listener.incoming() { 265 /// match stream { 266 /// Ok(stream) => { 267 /// thread::spawn(|| handle_client(stream)); 268 /// } 269 /// Err(err) => { 270 /// break; 271 /// } 272 /// } 273 /// } 274 /// Ok(()) 275 /// } 276 /// ``` 277 pub fn incoming(&self) -> Incoming<'_> { 278 Incoming { listener: self } 279 } 280 } 281 282 impl AsRawFd for UnixListener { 283 #[inline] 284 fn as_raw_fd(&self) -> RawFd { 285 self.0.as_inner().as_raw_fd() 286 } 287 } 288 289 impl FromRawFd for UnixListener { 290 #[inline] 291 unsafe fn from_raw_fd(fd: RawFd) -> UnixListener { 292 UnixListener(Socket::from_inner(FromInner::from_inner( 293 OwnedFd::from_raw_fd(fd), 294 ))) 295 } 296 } 297 298 impl IntoRawFd for UnixListener { 299 #[inline] 300 fn into_raw_fd(self) -> RawFd { 301 self.0.into_inner().into_inner().into_raw_fd() 302 } 303 } 304 305 impl AsFd for UnixListener { 306 #[inline] 307 fn as_fd(&self) -> BorrowedFd<'_> { 308 self.0.as_inner().as_fd() 309 } 310 } 311 312 impl From<OwnedFd> for UnixListener { 313 #[inline] 314 fn from(fd: OwnedFd) -> UnixListener { 315 UnixListener(Socket::from_inner(FromInner::from_inner(fd))) 316 } 317 } 318 319 impl From<UnixListener> for OwnedFd { 320 #[inline] 321 fn from(listener: UnixListener) -> OwnedFd { 322 listener.0.into_inner().into_inner() 323 } 324 } 325 326 impl<'a> IntoIterator for &'a UnixListener { 327 type Item = io::Result<UnixStream>; 328 type IntoIter = Incoming<'a>; 329 330 fn into_iter(self) -> Incoming<'a> { 331 self.incoming() 332 } 333 } 334 335 /// An iterator over incoming connections to a [`UnixListener`]. 336 /// 337 /// It will never return [`None`]. 338 /// 339 /// # Examples 340 /// 341 /// ```no_run 342 /// use std::thread; 343 /// use std::os::unix::net::{UnixStream, UnixListener}; 344 /// 345 /// fn handle_client(stream: UnixStream) { 346 /// // ... 347 /// } 348 /// 349 /// fn main() -> std::io::Result<()> { 350 /// let listener = UnixListener::bind("/path/to/the/socket")?; 351 /// 352 /// for stream in listener.incoming() { 353 /// match stream { 354 /// Ok(stream) => { 355 /// thread::spawn(|| handle_client(stream)); 356 /// } 357 /// Err(err) => { 358 /// break; 359 /// } 360 /// } 361 /// } 362 /// Ok(()) 363 /// } 364 /// ``` 365 #[derive(Debug)] 366 #[must_use = "iterators are lazy and do nothing unless consumed"] 367 pub struct Incoming<'a> { 368 listener: &'a UnixListener, 369 } 370 371 impl<'a> Iterator for Incoming<'a> { 372 type Item = io::Result<UnixStream>; 373 374 fn next(&mut self) -> Option<io::Result<UnixStream>> { 375 Some(self.listener.accept().map(|s| s.0)) 376 } 377 378 fn size_hint(&self) -> (usize, Option<usize>) { 379 (usize::MAX, None) 380 } 381 } 382