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}