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