Skip to main content

std/os/windows/net/
listener.rs

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