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