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: libc::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: libc::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(inner.as_inner().as_raw_fd(), &addr as *const _ as *const _, len as _))?;
103 cvt(libc::listen(inner.as_inner().as_raw_fd(), backlog))?;
104
105 Ok(UnixListener(inner))
106 }
107 }
108
109 /// Creates a new `UnixListener` bound to the specified [`socket address`].
110 ///
111 /// [`socket address`]: crate::os::unix::net::SocketAddr
112 ///
113 /// # Examples
114 ///
115 /// ```no_run
116 /// use std::os::unix::net::{UnixListener};
117 ///
118 /// fn main() -> std::io::Result<()> {
119 /// let listener1 = UnixListener::bind("path/to/socket")?;
120 /// let addr = listener1.local_addr()?;
121 ///
122 /// let listener2 = match UnixListener::bind_addr(&addr) {
123 /// Ok(sock) => sock,
124 /// Err(err) => {
125 /// println!("Couldn't bind: {err:?}");
126 /// return Err(err);
127 /// }
128 /// };
129 /// Ok(())
130 /// }
131 /// ```
132 #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
133 pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result<UnixListener> {
134 unsafe {
135 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
136 #[cfg(target_os = "linux")]
137 const backlog: libc::c_int = -1;
138 #[cfg(not(target_os = "linux"))]
139 const backlog: libc::c_int = 128;
140 cvt(libc::bind(
141 inner.as_raw_fd(),
142 &socket_addr.addr as *const _ as *const _,
143 socket_addr.len as _,
144 ))?;
145 cvt(libc::listen(inner.as_raw_fd(), backlog))?;
146 Ok(UnixListener(inner))
147 }
148 }
149
150 /// Accepts a new incoming connection to this listener.
151 ///
152 /// This function will block the calling thread until a new Unix connection
153 /// is established. When established, the corresponding [`UnixStream`] and
154 /// the remote peer's address will be returned.
155 ///
156 /// [`UnixStream`]: crate::os::unix::net::UnixStream
157 ///
158 /// # Examples
159 ///
160 /// ```no_run
161 /// use std::os::unix::net::UnixListener;
162 ///
163 /// fn main() -> std::io::Result<()> {
164 /// let listener = UnixListener::bind("/path/to/the/socket")?;
165 ///
166 /// match listener.accept() {
167 /// Ok((socket, addr)) => println!("Got a client: {addr:?}"),
168 /// Err(e) => println!("accept function failed: {e:?}"),
169 /// }
170 /// Ok(())
171 /// }
172 /// ```
173 #[stable(feature = "unix_socket", since = "1.10.0")]
174 pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
175 let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() };
176 let mut len = mem::size_of_val(&storage) as libc::socklen_t;
177 let sock = self.0.accept(&mut storage as *mut _ as *mut _, &mut len)?;
178 let addr = SocketAddr::from_parts(storage, len)?;
179 Ok((UnixStream(sock), addr))
180 }
181
182 /// Creates a new independently owned handle to the underlying socket.
183 ///
184 /// The returned `UnixListener` is a reference to the same socket that this
185 /// object references. Both handles can be used to accept incoming
186 /// connections and options set on one listener will affect the other.
187 ///
188 /// # Examples
189 ///
190 /// ```no_run
191 /// use std::os::unix::net::UnixListener;
192 ///
193 /// fn main() -> std::io::Result<()> {
194 /// let listener = UnixListener::bind("/path/to/the/socket")?;
195 /// let listener_copy = listener.try_clone().expect("try_clone failed");
196 /// Ok(())
197 /// }
198 /// ```
199 #[stable(feature = "unix_socket", since = "1.10.0")]
200 pub fn try_clone(&self) -> io::Result<UnixListener> {
201 self.0.duplicate().map(UnixListener)
202 }
203
204 /// Returns the local socket address of this listener.
205 ///
206 /// # Examples
207 ///
208 /// ```no_run
209 /// use std::os::unix::net::UnixListener;
210 ///
211 /// fn main() -> std::io::Result<()> {
212 /// let listener = UnixListener::bind("/path/to/the/socket")?;
213 /// let addr = listener.local_addr().expect("Couldn't get local address");
214 /// Ok(())
215 /// }
216 /// ```
217 #[stable(feature = "unix_socket", since = "1.10.0")]
218 pub fn local_addr(&self) -> io::Result<SocketAddr> {
219 SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.as_raw_fd(), addr, len) })
220 }
221
222 /// Moves the socket into or out of nonblocking mode.
223 ///
224 /// This will result in the `accept` operation becoming nonblocking,
225 /// i.e., immediately returning from their calls. If the IO operation is
226 /// successful, `Ok` is returned and no further action is required. If the
227 /// IO operation could not be completed and needs to be retried, an error
228 /// with kind [`io::ErrorKind::WouldBlock`] is returned.
229 ///
230 /// # Examples
231 ///
232 /// ```no_run
233 /// use std::os::unix::net::UnixListener;
234 ///
235 /// fn main() -> std::io::Result<()> {
236 /// let listener = UnixListener::bind("/path/to/the/socket")?;
237 /// listener.set_nonblocking(true).expect("Couldn't set non blocking");
238 /// Ok(())
239 /// }
240 /// ```
241 #[stable(feature = "unix_socket", since = "1.10.0")]
242 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
243 self.0.set_nonblocking(nonblocking)
244 }
245
246 /// Returns the value of the `SO_ERROR` option.
247 ///
248 /// # Examples
249 ///
250 /// ```no_run
251 /// use std::os::unix::net::UnixListener;
252 ///
253 /// fn main() -> std::io::Result<()> {
254 /// let listener = UnixListener::bind("/tmp/sock")?;
255 ///
256 /// if let Ok(Some(err)) = listener.take_error() {
257 /// println!("Got error: {err:?}");
258 /// }
259 /// Ok(())
260 /// }
261 /// ```
262 ///
263 /// # Platform specific
264 /// On Redox this always returns `None`.
265 #[stable(feature = "unix_socket", since = "1.10.0")]
266 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
267 self.0.take_error()
268 }
269
270 /// Returns an iterator over incoming connections.
271 ///
272 /// The iterator will never return [`None`] and will also not yield the
273 /// peer's [`SocketAddr`] structure.
274 ///
275 /// # Examples
276 ///
277 /// ```no_run
278 /// use std::thread;
279 /// use std::os::unix::net::{UnixStream, UnixListener};
280 ///
281 /// fn handle_client(stream: UnixStream) {
282 /// // ...
283 /// }
284 ///
285 /// fn main() -> std::io::Result<()> {
286 /// let listener = UnixListener::bind("/path/to/the/socket")?;
287 ///
288 /// for stream in listener.incoming() {
289 /// match stream {
290 /// Ok(stream) => {
291 /// thread::spawn(|| handle_client(stream));
292 /// }
293 /// Err(err) => {
294 /// break;
295 /// }
296 /// }
297 /// }
298 /// Ok(())
299 /// }
300 /// ```
301 #[stable(feature = "unix_socket", since = "1.10.0")]
302 pub fn incoming(&self) -> Incoming<'_> {
303 Incoming { listener: self }
304 }
305}
306
307#[stable(feature = "unix_socket", since = "1.10.0")]
308impl AsRawFd for UnixListener {
309 #[inline]
310 fn as_raw_fd(&self) -> RawFd {
311 self.0.as_inner().as_raw_fd()
312 }
313}
314
315#[stable(feature = "unix_socket", since = "1.10.0")]
316impl FromRawFd for UnixListener {
317 #[inline]
318 unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
319 UnixListener(Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd))))
320 }
321}
322
323#[stable(feature = "unix_socket", since = "1.10.0")]
324impl IntoRawFd for UnixListener {
325 #[inline]
326 fn into_raw_fd(self) -> RawFd {
327 self.0.into_inner().into_inner().into_raw_fd()
328 }
329}
330
331#[stable(feature = "io_safety", since = "1.63.0")]
332impl AsFd for UnixListener {
333 #[inline]
334 fn as_fd(&self) -> BorrowedFd<'_> {
335 self.0.as_inner().as_fd()
336 }
337}
338
339#[stable(feature = "io_safety", since = "1.63.0")]
340impl From<OwnedFd> for UnixListener {
341 #[inline]
342 fn from(fd: OwnedFd) -> UnixListener {
343 UnixListener(Socket::from_inner(FromInner::from_inner(fd)))
344 }
345}
346
347#[stable(feature = "io_safety", since = "1.63.0")]
348impl From<UnixListener> for OwnedFd {
349 #[inline]
350 fn from(listener: UnixListener) -> OwnedFd {
351 listener.0.into_inner().into_inner()
352 }
353}
354
355#[stable(feature = "unix_socket", since = "1.10.0")]
356impl<'a> IntoIterator for &'a UnixListener {
357 type Item = io::Result<UnixStream>;
358 type IntoIter = Incoming<'a>;
359
360 fn into_iter(self) -> Incoming<'a> {
361 self.incoming()
362 }
363}
364
365/// An iterator over incoming connections to a [`UnixListener`].
366///
367/// It will never return [`None`].
368///
369/// # Examples
370///
371/// ```no_run
372/// use std::thread;
373/// use std::os::unix::net::{UnixStream, UnixListener};
374///
375/// fn handle_client(stream: UnixStream) {
376/// // ...
377/// }
378///
379/// fn main() -> std::io::Result<()> {
380/// let listener = UnixListener::bind("/path/to/the/socket")?;
381///
382/// for stream in listener.incoming() {
383/// match stream {
384/// Ok(stream) => {
385/// thread::spawn(|| handle_client(stream));
386/// }
387/// Err(err) => {
388/// break;
389/// }
390/// }
391/// }
392/// Ok(())
393/// }
394/// ```
395#[derive(Debug)]
396#[must_use = "iterators are lazy and do nothing unless consumed"]
397#[stable(feature = "unix_socket", since = "1.10.0")]
398pub struct Incoming<'a> {
399 listener: &'a UnixListener,
400}
401
402#[stable(feature = "unix_socket", since = "1.10.0")]
403impl<'a> Iterator for Incoming<'a> {
404 type Item = io::Result<UnixStream>;
405
406 fn next(&mut self) -> Option<io::Result<UnixStream>> {
407 Some(self.listener.accept().map(|s: (UnixStream, SocketAddr)| s.0))
408 }
409
410 fn size_hint(&self) -> (usize, Option<usize>) {
411 (usize::MAX, None)
412 }
413}
414