std/os/windows/net/stream.rs
1#![unstable(feature = "windows_unix_domain_sockets", issue = "150487")]
2use crate::net::Shutdown;
3use crate::os::windows::io::{
4 AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, RawSocket,
5};
6use crate::os::windows::net::SocketAddr;
7use crate::path::Path;
8#[cfg(not(doc))]
9use crate::sys::c::{
10 AF_UNIX, SO_RCVTIMEO, SO_SNDTIMEO, SOCK_STREAM, connect, getpeername, getsockname,
11};
12use crate::sys::net::Socket;
13#[cfg(not(doc))]
14use crate::sys::winsock::startup;
15use crate::sys::{AsInner, cvt_nz};
16use crate::time::Duration;
17use crate::{fmt, io};
18/// A Unix stream socket.
19///
20/// # Examples
21///
22/// ```no_run
23/// #![feature(windows_unix_domain_sockets)]
24/// use std::os::windows::net::UnixStream;
25/// use std::io::prelude::*;
26///
27/// fn main() -> std::io::Result<()> {
28/// let mut stream = UnixStream::connect("/path/to/my/socket")?;
29/// stream.write_all(b"hello world")?;
30/// let mut response = String::new();
31/// stream.read_to_string(&mut response)?;
32/// println!("{response}");
33/// Ok(())
34/// }
35/// ```
36pub struct UnixStream(pub(super) Socket);
37impl fmt::Debug for UnixStream {
38 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
39 let mut builder = fmt.debug_struct("UnixStream");
40 builder.field("sock", self.0.as_inner());
41 if let Ok(addr) = self.local_addr() {
42 builder.field("local", &addr);
43 }
44 if let Ok(addr) = self.peer_addr() {
45 builder.field("peer", &addr);
46 }
47 builder.finish()
48 }
49}
50impl UnixStream {
51 /// Connects to the socket named by `path`.
52 ///
53 /// # Examples
54 ///
55 /// ```no_run
56 /// #![feature(windows_unix_domain_sockets)]
57 /// use std::os::windows::net::UnixStream;
58 ///
59 /// let socket = match UnixStream::connect("/tmp/sock") {
60 /// Ok(sock) => sock,
61 /// Err(e) => {
62 /// println!("Couldn't connect: {e:?}");
63 /// return
64 /// }
65 /// };
66 /// ```
67 pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
68 let socket_addr = SocketAddr::from_pathname(path)?;
69 Self::connect_addr(&socket_addr)
70 }
71
72 /// Connects to the socket specified by [`address`].
73 ///
74 /// [`address`]: crate::os::windows::net::SocketAddr
75 ///
76 /// # Examples
77 ///
78 /// ```no_run
79 /// #![feature(windows_unix_domain_sockets)]
80 /// use std::os::windows::net::{UnixListener, UnixStream};
81 ///
82 /// fn main() -> std::io::Result<()> {
83 /// let listener = UnixListener::bind("/path/to/the/socket")?;
84 /// let addr = listener.local_addr()?;
85 ///
86 /// let sock = match UnixStream::connect_addr(&addr) {
87 /// Ok(sock) => sock,
88 /// Err(e) => {
89 /// println!("Couldn't connect: {e:?}");
90 /// return Err(e)
91 /// }
92 /// };
93 /// Ok(())
94 /// }
95 /// ````
96 pub fn connect_addr(socket_addr: &SocketAddr) -> io::Result<UnixStream> {
97 startup();
98 let inner = Socket::new(AF_UNIX as _, SOCK_STREAM)?;
99 unsafe {
100 cvt_nz(connect(
101 inner.as_raw(),
102 &raw const socket_addr.addr as *const _,
103 socket_addr.len as _,
104 ))?;
105 }
106 Ok(UnixStream(inner))
107 }
108
109 /// Returns the socket address of the local half of this connection.
110 ///
111 /// # Examples
112 ///
113 /// ```no_run
114 /// #![feature(windows_unix_domain_sockets)]
115 /// use std::os::windows::net::UnixStream;
116 ///
117 /// fn main() -> std::io::Result<()> {
118 /// let socket = UnixStream::connect("/tmp/sock")?;
119 /// let addr = socket.local_addr().expect("Couldn't get local address");
120 /// Ok(())
121 /// }
122 /// ```
123 pub fn local_addr(&self) -> io::Result<SocketAddr> {
124 SocketAddr::new(|addr, len| unsafe { getsockname(self.0.as_raw(), addr, len) })
125 }
126
127 /// Returns the socket address of the remote half of this connection.
128 ///
129 /// # Examples
130 ///
131 /// ```no_run
132 /// #![feature(windows_unix_domain_sockets)]
133 /// use std::os::windows::net::UnixStream;
134 ///
135 /// fn main() -> std::io::Result<()> {
136 /// let socket = UnixStream::connect("/tmp/sock")?;
137 /// let addr = socket.peer_addr().expect("Couldn't get peer address");
138 /// Ok(())
139 /// }
140 /// ```
141 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
142 SocketAddr::new(|addr, len| unsafe { getpeername(self.0.as_raw(), addr, len) })
143 }
144
145 /// Returns the read timeout of this socket.
146 ///
147 /// # Examples
148 ///
149 /// ```no_run
150 /// #![feature(windows_unix_domain_sockets)]
151 /// use std::os::windows::net::UnixStream;
152 /// use std::time::Duration;
153 ///
154 /// fn main() -> std::io::Result<()> {
155 /// let socket = UnixStream::connect("/tmp/sock")?;
156 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
157 /// assert_eq!(socket.read_timeout()?, Some(Duration::new(1, 0)));
158 /// Ok(())
159 /// }
160 /// ```
161 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
162 self.0.timeout(SO_RCVTIMEO)
163 }
164
165 /// Moves the socket into or out of nonblocking mode.
166 ///
167 /// # Examples
168 ///
169 /// ```no_run
170 /// #![feature(windows_unix_domain_sockets)]
171 /// use std::os::windows::net::UnixStream;
172 ///
173 /// fn main() -> std::io::Result<()> {
174 /// let socket = UnixStream::connect("/tmp/sock")?;
175 /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
176 /// Ok(())
177 /// }
178 /// ```
179 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
180 self.0.set_nonblocking(nonblocking)
181 }
182
183 /// Sets the read timeout for the socket.
184 ///
185 /// If the provided value is [`None`], then [`read`] calls will block
186 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
187 /// method.
188 ///
189 /// [`read`]: io::Read::read
190 ///
191 /// # Examples
192 ///
193 /// ```no_run
194 /// #![feature(windows_unix_domain_sockets)]
195 /// use std::os::windows::net::UnixStream;
196 /// use std::time::Duration;
197 ///
198 /// fn main() -> std::io::Result<()> {
199 /// let socket = UnixStream::connect("/tmp/sock")?;
200 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
201 /// Ok(())
202 /// }
203 /// ```
204 ///
205 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
206 /// method:
207 ///
208 /// ```no_run
209 /// #![feature(windows_unix_domain_sockets)]
210 /// use std::io;
211 /// use std::os::windows::net::UnixStream;
212 /// use std::time::Duration;
213 ///
214 /// fn main() -> std::io::Result<()> {
215 /// let socket = UnixStream::connect("/tmp/sock")?;
216 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
217 /// let err = result.unwrap_err();
218 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
219 /// Ok(())
220 /// }
221 /// ```
222 pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
223 self.0.set_timeout(dur, SO_RCVTIMEO)
224 }
225
226 /// Sets the write timeout for the socket.
227 ///
228 /// If the provided value is [`None`], then [`write`] calls will block
229 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
230 /// passed to this method.
231 ///
232 /// [`read`]: io::Read::read
233 ///
234 /// # Examples
235 ///
236 /// ```no_run
237 /// #![feature(windows_unix_domain_sockets)]
238 /// use std::os::windows::net::UnixStream;
239 /// use std::time::Duration;
240 ///
241 /// fn main() -> std::io::Result<()> {
242 /// let socket = UnixStream::connect("/tmp/sock")?;
243 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
244 /// .expect("Couldn't set write timeout");
245 /// Ok(())
246 /// }
247 /// ```
248 ///
249 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
250 /// method:
251 ///
252 /// ```no_run
253 /// #![feature(windows_unix_domain_sockets)]
254 /// use std::io;
255 /// use std::os::windows::net::UnixStream;
256 /// use std::time::Duration;
257 ///
258 /// fn main() -> std::io::Result<()> {
259 /// let socket = UnixStream::connect("/tmp/sock")?;
260 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
261 /// let err = result.unwrap_err();
262 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
263 /// Ok(())
264 /// }
265 /// ```
266 pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
267 self.0.set_timeout(dur, SO_SNDTIMEO)
268 }
269
270 /// Shuts down the read, write, or both halves of this connection.
271 ///
272 /// This function will cause all pending and future I/O calls on the
273 /// specified portions to immediately return with an appropriate value
274 /// (see the documentation of [`Shutdown`]).
275 ///
276 /// # Examples
277 ///
278 /// ```no_run
279 /// #![feature(windows_unix_domain_sockets)]
280 /// use std::os::windows::net::UnixStream;
281 /// use std::net::Shutdown;
282 ///
283 /// fn main() -> std::io::Result<()> {
284 /// let socket = UnixStream::connect("/tmp/sock")?;
285 /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
286 /// Ok(())
287 /// }
288 /// ```
289 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
290 self.0.shutdown(how)
291 }
292
293 /// Returns the value of the `SO_ERROR` option.
294 ///
295 /// # Examples
296 ///
297 /// ```no_run
298 /// #![feature(windows_unix_domain_sockets)]
299 /// use std::os::windows::net::UnixStream;
300 ///
301 /// fn main() -> std::io::Result<()> {
302 /// let socket = UnixStream::connect("/tmp/sock")?;
303 /// if let Ok(Some(err)) = socket.take_error() {
304 /// println!("Got error: {err:?}");
305 /// }
306 /// Ok(())
307 /// }
308 /// ```
309 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
310 self.0.take_error()
311 }
312
313 /// Creates a new independently owned handle to the underlying socket.
314 ///
315 /// The returned `UnixStream` is a reference to the same stream that this
316 /// object references. Both handles will read and write the same stream of
317 /// data, and options set on one stream will be propagated to the other
318 /// stream.
319 ///
320 /// # Examples
321 ///
322 /// ```no_run
323 /// #![feature(windows_unix_domain_sockets)]
324 /// use std::os::windows::net::UnixStream;
325 ///
326 /// fn main() -> std::io::Result<()> {
327 /// let socket = UnixStream::connect("/tmp/sock")?;
328 /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
329 /// Ok(())
330 /// }
331 /// ```
332 pub fn try_clone(&self) -> io::Result<UnixStream> {
333 self.0.duplicate().map(UnixStream)
334 }
335
336 /// Returns the write timeout of this socket.
337 ///
338 /// # Examples
339 ///
340 /// ```no_run
341 /// #![feature(windows_unix_domain_sockets)]
342 /// use std::os::windows::net::UnixStream;
343 /// use std::time::Duration;
344 ///
345 /// fn main() -> std::io::Result<()> {
346 /// let socket = UnixStream::connect("/tmp/sock")?;
347 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
348 /// .expect("Couldn't set write timeout");
349 /// assert_eq!(socket.write_timeout()?, Some(Duration::new(1, 0)));
350 /// Ok(())
351 /// }
352 /// ```
353 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
354 self.0.timeout(SO_SNDTIMEO)
355 }
356}
357
358impl io::Read for UnixStream {
359 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
360 io::Read::read(&mut &*self, buf)
361 }
362}
363
364impl<'a> io::Read for &'a UnixStream {
365 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
366 self.0.read(buf)
367 }
368}
369
370impl io::Write for UnixStream {
371 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
372 io::Write::write(&mut &*self, buf)
373 }
374
375 fn flush(&mut self) -> io::Result<()> {
376 io::Write::flush(&mut &*self)
377 }
378}
379impl<'a> io::Write for &'a UnixStream {
380 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
381 self.write_vectored(&[io::IoSlice::new(buf)])
382 }
383 #[inline]
384 fn flush(&mut self) -> io::Result<()> {
385 Ok(())
386 }
387 fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
388 self.0.write_vectored(bufs)
389 }
390 #[inline]
391 fn is_write_vectored(&self) -> bool {
392 self.0.is_write_vectored()
393 }
394}
395
396impl AsSocket for UnixStream {
397 #[inline]
398 fn as_socket(&self) -> BorrowedSocket<'_> {
399 self.0.as_socket()
400 }
401}
402
403impl AsRawSocket for UnixStream {
404 #[inline]
405 fn as_raw_socket(&self) -> RawSocket {
406 self.0.as_raw_socket()
407 }
408}
409
410impl FromRawSocket for UnixStream {
411 #[inline]
412 unsafe fn from_raw_socket(sock: RawSocket) -> Self {
413 unsafe { UnixStream(Socket::from_raw_socket(sock)) }
414 }
415}
416
417impl IntoRawSocket for UnixStream {
418 fn into_raw_socket(self) -> RawSocket {
419 self.0.into_raw_socket()
420 }
421}