std/os/unix/net/stream.rs
1cfg_select! {
2 any(
3 target_os = "linux",
4 target_os = "android",
5 target_os = "hurd",
6 target_os = "dragonfly",
7 target_os = "freebsd",
8 target_os = "openbsd",
9 target_os = "netbsd",
10 target_os = "solaris",
11 target_os = "illumos",
12 target_os = "haiku",
13 target_os = "nto",
14 target_os = "qnx",
15 target_os = "cygwin",
16 ) => {
17 use libc::MSG_NOSIGNAL;
18 }
19 _ => {
20 const MSG_NOSIGNAL: core::ffi::c_int = 0x0;
21 }
22}
23
24use super::{SocketAddr, sockaddr_un};
25#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
26use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to};
27#[cfg(any(
28 target_os = "android",
29 target_os = "linux",
30 target_os = "dragonfly",
31 target_os = "freebsd",
32 target_os = "netbsd",
33 target_os = "openbsd",
34 target_os = "nto",
35 target_os = "qnx",
36 target_vendor = "apple",
37 target_os = "cygwin"
38))]
39use super::{UCred, peer_cred};
40use crate::fmt;
41use crate::io::{self, IoSlice, IoSliceMut};
42use crate::macros::rustdoc_skip_body;
43use crate::net::Shutdown;
44use crate::os::unix::io::{
45 AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd, unsafe_impl_fd_asrefs,
46};
47use crate::path::Path;
48use crate::sys::net::Socket;
49use crate::sys::{AsInner, FromInner, cvt};
50use crate::time::Duration;
51
52/// A Unix stream socket.
53///
54/// # Examples
55///
56#[cfg_attr(target_family = "unix", doc = "```no_run")]
57#[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
58/// use std::os::unix::net::UnixStream;
59/// use std::io::prelude::*;
60///
61/// fn main() -> std::io::Result<()> {
62/// let mut stream = UnixStream::connect("/path/to/my/socket")?;
63/// stream.write_all(b"hello world")?;
64/// let mut response = String::new();
65/// stream.read_to_string(&mut response)?;
66/// println!("{response}");
67/// Ok(())
68/// }
69/// ```
70///
71/// # `SOCK_CLOEXEC`
72///
73/// On platforms that support it, we pass the close-on-exec flag to atomically create the socket and
74/// set it as CLOEXEC. On Linux, this was added in 2.6.27. See [`socket(2)`] for more information.
75///
76/// [`socket(2)`]: https://www.man7.org/linux/man-pages/man2/socket.2.html#:~:text=SOCK_CLOEXEC
77///
78/// # `SIGPIPE`
79///
80/// Writes to the underlying socket in `SOCK_STREAM` mode are made with `MSG_NOSIGNAL` flag.
81/// This suppresses the emission of the `SIGPIPE` signal when writing to disconnected socket.
82/// In some cases getting a `SIGPIPE` would trigger process termination.
83#[stable(feature = "unix_socket", since = "1.10.0")]
84pub struct UnixStream(pub(super) Socket);
85
86#[stable(feature = "unix_socket", since = "1.10.0")]
87impl fmt::Debug for UnixStream {
88 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
89 let mut builder = fmt.debug_struct("UnixStream");
90 builder.field("fd", self.0.as_inner());
91 if let Ok(addr) = self.local_addr() {
92 builder.field("local", &addr);
93 }
94 if let Ok(addr) = self.peer_addr() {
95 builder.field("peer", &addr);
96 }
97 builder.finish()
98 }
99}
100
101impl UnixStream {
102 /// Connects to the socket named by `path`.
103 ///
104 /// # Examples
105 ///
106 #[cfg_attr(target_family = "unix", doc = "```no_run")]
107 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
108 /// use std::os::unix::net::UnixStream;
109 ///
110 /// let socket = match UnixStream::connect("/tmp/sock") {
111 /// Ok(sock) => sock,
112 /// Err(e) => {
113 /// println!("Couldn't connect: {e:?}");
114 /// return
115 /// }
116 /// };
117 /// ```
118 #[stable(feature = "unix_socket", since = "1.10.0")]
119 pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
120 unsafe {
121 let inner = Socket::new(libc::AF_UNIX, libc::SOCK_STREAM)?;
122 let (addr, len) = sockaddr_un(path.as_ref())?;
123
124 cvt(libc::connect(inner.as_raw_fd(), (&raw const addr) as *const _, len))?;
125 Ok(UnixStream(inner))
126 }
127 }
128
129 /// Connects to the socket specified by [`address`].
130 ///
131 /// [`address`]: crate::os::unix::net::SocketAddr
132 ///
133 /// # Examples
134 ///
135 #[cfg_attr(target_family = "unix", doc = "```no_run")]
136 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
137 /// use std::os::unix::net::{UnixListener, UnixStream};
138 ///
139 /// fn main() -> std::io::Result<()> {
140 /// let listener = UnixListener::bind("/path/to/the/socket")?;
141 /// let addr = listener.local_addr()?;
142 ///
143 /// let sock = match UnixStream::connect_addr(&addr) {
144 /// Ok(sock) => sock,
145 /// Err(e) => {
146 /// println!("Couldn't connect: {e:?}");
147 /// return Err(e)
148 /// }
149 /// };
150 /// Ok(())
151 /// }
152 /// ```
153 #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
154 pub fn connect_addr(socket_addr: &SocketAddr) -> io::Result<UnixStream> {
155 unsafe {
156 let inner = Socket::new(libc::AF_UNIX, libc::SOCK_STREAM)?;
157 cvt(libc::connect(
158 inner.as_raw_fd(),
159 (&raw const socket_addr.addr) as *const _,
160 socket_addr.len,
161 ))?;
162 Ok(UnixStream(inner))
163 }
164 }
165
166 /// Creates an unnamed pair of connected sockets.
167 ///
168 /// Returns two `UnixStream`s which are connected to each other.
169 ///
170 /// # Examples
171 ///
172 #[cfg_attr(target_family = "unix", doc = "```no_run")]
173 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
174 /// use std::os::unix::net::UnixStream;
175 ///
176 /// let (sock1, sock2) = match UnixStream::pair() {
177 /// Ok((sock1, sock2)) => (sock1, sock2),
178 /// Err(e) => {
179 /// println!("Couldn't create a pair of sockets: {e:?}");
180 /// return
181 /// }
182 /// };
183 /// ```
184 #[stable(feature = "unix_socket", since = "1.10.0")]
185 pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
186 let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
187 Ok((UnixStream(i1), UnixStream(i2)))
188 }
189
190 /// Creates a new independently owned handle to the underlying socket.
191 ///
192 /// The returned `UnixStream` is a reference to the same stream that this
193 /// object references. Both handles will read and write the same stream of
194 /// data, and options set on one stream will be propagated to the other
195 /// stream.
196 ///
197 /// # Examples
198 ///
199 #[cfg_attr(target_family = "unix", doc = "```no_run")]
200 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
201 /// use std::os::unix::net::UnixStream;
202 ///
203 /// fn main() -> std::io::Result<()> {
204 /// let socket = UnixStream::connect("/tmp/sock")?;
205 /// let sock_copy = socket.try_clone().expect("`UnixStream::try_clone` should not fail");
206 /// Ok(())
207 /// }
208 /// ```
209 #[stable(feature = "unix_socket", since = "1.10.0")]
210 pub fn try_clone(&self) -> io::Result<UnixStream> {
211 self.0.duplicate().map(UnixStream)
212 }
213
214 /// Returns the socket address of the local half of this connection.
215 ///
216 /// # Examples
217 ///
218 #[cfg_attr(target_family = "unix", doc = "```no_run")]
219 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
220 /// use std::os::unix::net::UnixStream;
221 ///
222 /// fn main() -> std::io::Result<()> {
223 /// let socket = UnixStream::connect("/tmp/sock")?;
224 /// let addr = socket.local_addr().expect("`UnixStream::local_addr` should not fail");
225 /// Ok(())
226 /// }
227 /// ```
228 #[stable(feature = "unix_socket", since = "1.10.0")]
229 #[rustdoc_skip_body]
230 pub fn local_addr(&self) -> io::Result<SocketAddr> {
231 SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.as_raw_fd(), addr, len) })
232 }
233
234 /// Returns the socket address of the remote half of this connection.
235 ///
236 /// # Examples
237 ///
238 #[cfg_attr(target_family = "unix", doc = "```no_run")]
239 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
240 /// use std::os::unix::net::UnixStream;
241 ///
242 /// fn main() -> std::io::Result<()> {
243 /// let socket = UnixStream::connect("/tmp/sock")?;
244 /// let addr = socket.peer_addr().expect("`UnixStream::peer_addr` should not fail");
245 /// Ok(())
246 /// }
247 /// ```
248 #[stable(feature = "unix_socket", since = "1.10.0")]
249 #[rustdoc_skip_body]
250 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
251 SocketAddr::new(|addr, len| unsafe { libc::getpeername(self.as_raw_fd(), addr, len) })
252 }
253
254 /// Gets the peer credentials for this Unix domain socket.
255 ///
256 /// # Examples
257 ///
258 #[cfg_attr(target_family = "unix", doc = "```no_run")]
259 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
260 /// #![feature(peer_credentials_unix_socket)]
261 /// use std::os::unix::net::UnixStream;
262 ///
263 /// fn main() -> std::io::Result<()> {
264 /// let socket = UnixStream::connect("/tmp/sock")?;
265 /// let peer_cred = socket.peer_cred().expect("`UnixStream::peer_cred` should not fail");
266 /// Ok(())
267 /// }
268 /// ```
269 #[unstable(feature = "peer_credentials_unix_socket", issue = "42839")]
270 #[cfg(any(
271 target_os = "android",
272 target_os = "linux",
273 target_os = "dragonfly",
274 target_os = "freebsd",
275 target_os = "netbsd",
276 target_os = "openbsd",
277 target_os = "nto",
278 target_os = "qnx",
279 target_vendor = "apple",
280 target_os = "cygwin"
281 ))]
282 pub fn peer_cred(&self) -> io::Result<UCred> {
283 peer_cred(self)
284 }
285
286 /// Sets the read timeout for the socket.
287 ///
288 /// If the provided value is [`None`], then [`read`] calls will block
289 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
290 /// method.
291 ///
292 /// [`read`]: io::Read::read
293 ///
294 /// # Examples
295 ///
296 #[cfg_attr(target_family = "unix", doc = "```no_run")]
297 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
298 /// use std::os::unix::net::UnixStream;
299 /// use std::time::Duration;
300 ///
301 /// fn main() -> std::io::Result<()> {
302 /// let socket = UnixStream::connect("/tmp/sock")?;
303 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("`UnixStream::set_read_timeout` should not fail");
304 /// Ok(())
305 /// }
306 /// ```
307 ///
308 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
309 /// method:
310 ///
311 #[cfg_attr(target_family = "unix", doc = "```no_run")]
312 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
313 /// use std::io;
314 /// use std::os::unix::net::UnixStream;
315 /// use std::time::Duration;
316 ///
317 /// fn main() -> std::io::Result<()> {
318 /// let socket = UnixStream::connect("/tmp/sock")?;
319 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
320 /// let err = result.unwrap_err();
321 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
322 /// Ok(())
323 /// }
324 /// ```
325 #[stable(feature = "unix_socket", since = "1.10.0")]
326 #[rustdoc_skip_body]
327 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
328 self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
329 }
330
331 /// Sets the write timeout for the socket.
332 ///
333 /// If the provided value is [`None`], then [`write`] calls will block
334 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
335 /// passed to this method.
336 ///
337 /// [`read`]: io::Read::read
338 ///
339 /// # Examples
340 ///
341 #[cfg_attr(target_family = "unix", doc = "```no_run")]
342 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
343 /// use std::os::unix::net::UnixStream;
344 /// use std::time::Duration;
345 ///
346 /// fn main() -> std::io::Result<()> {
347 /// let socket = UnixStream::connect("/tmp/sock")?;
348 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
349 /// .expect("`UnixStream::connect` should not fail");
350 /// Ok(())
351 /// }
352 /// ```
353 ///
354 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
355 /// method:
356 ///
357 #[cfg_attr(target_family = "unix", doc = "```no_run")]
358 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
359 /// use std::io;
360 /// use std::os::unix::net::UnixStream;
361 /// use std::time::Duration;
362 ///
363 /// fn main() -> std::io::Result<()> {
364 /// let socket = UnixStream::connect("/tmp/sock")?;
365 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
366 /// let err = result.unwrap_err();
367 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
368 /// Ok(())
369 /// }
370 /// ```
371 #[stable(feature = "unix_socket", since = "1.10.0")]
372 #[rustdoc_skip_body]
373 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
374 self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
375 }
376
377 /// Returns the read timeout of this socket.
378 ///
379 /// # Examples
380 ///
381 #[cfg_attr(target_family = "unix", doc = "```no_run")]
382 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
383 /// use std::os::unix::net::UnixStream;
384 /// use std::time::Duration;
385 ///
386 /// fn main() -> std::io::Result<()> {
387 /// let socket = UnixStream::connect("/tmp/sock")?;
388 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("`UnixStream::set_read_timeout` should not fail");
389 /// assert_eq!(socket.read_timeout()?, Some(Duration::new(1, 0)));
390 /// Ok(())
391 /// }
392 /// ```
393 #[stable(feature = "unix_socket", since = "1.10.0")]
394 #[rustdoc_skip_body]
395 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
396 self.0.timeout(libc::SO_RCVTIMEO)
397 }
398
399 /// Returns the write timeout of this socket.
400 ///
401 /// # Examples
402 ///
403 #[cfg_attr(target_family = "unix", doc = "```no_run")]
404 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
405 /// use std::os::unix::net::UnixStream;
406 /// use std::time::Duration;
407 ///
408 /// fn main() -> std::io::Result<()> {
409 /// let socket = UnixStream::connect("/tmp/sock")?;
410 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
411 /// .expect("`UnixStream::set_write_timeout` should not fail");
412 /// assert_eq!(socket.write_timeout()?, Some(Duration::new(1, 0)));
413 /// Ok(())
414 /// }
415 /// ```
416 #[stable(feature = "unix_socket", since = "1.10.0")]
417 #[rustdoc_skip_body]
418 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
419 self.0.timeout(libc::SO_SNDTIMEO)
420 }
421
422 /// Moves the socket into or out of nonblocking mode.
423 ///
424 /// # Examples
425 ///
426 #[cfg_attr(target_family = "unix", doc = "```no_run")]
427 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
428 /// use std::os::unix::net::UnixStream;
429 ///
430 /// fn main() -> std::io::Result<()> {
431 /// let socket = UnixStream::connect("/tmp/sock")?;
432 /// socket.set_nonblocking(true).expect("`UnixStream::set_nonblocking` should not fail");
433 /// Ok(())
434 /// }
435 /// ```
436 #[stable(feature = "unix_socket", since = "1.10.0")]
437 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
438 self.0.set_nonblocking(nonblocking)
439 }
440
441 /// Set the id of the socket for network filtering purpose
442 ///
443 #[cfg_attr(
444 any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"),
445 doc = "```no_run"
446 )]
447 #[cfg_attr(
448 not(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd")),
449 doc = "```ignore"
450 )]
451 /// #![feature(unix_set_mark)]
452 /// use std::os::unix::net::UnixStream;
453 ///
454 /// fn main() -> std::io::Result<()> {
455 /// let sock = UnixStream::connect("/tmp/sock")?;
456 /// sock.set_mark(32)?;
457 /// Ok(())
458 /// }
459 /// ```
460 #[cfg(any(doc, target_os = "linux", target_os = "freebsd", target_os = "openbsd",))]
461 #[unstable(feature = "unix_set_mark", issue = "96467")]
462 #[rustdoc_skip_body]
463 pub fn set_mark(&self, mark: u32) -> io::Result<()> {
464 self.0.set_mark(mark)
465 }
466
467 /// Returns the value of the `SO_ERROR` option.
468 ///
469 /// # Examples
470 ///
471 #[cfg_attr(target_family = "unix", doc = "```no_run")]
472 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
473 /// use std::os::unix::net::UnixStream;
474 ///
475 /// fn main() -> std::io::Result<()> {
476 /// let socket = UnixStream::connect("/tmp/sock")?;
477 /// if let Ok(Some(err)) = socket.take_error() {
478 /// println!("Got error: {err:?}");
479 /// }
480 /// Ok(())
481 /// }
482 /// ```
483 ///
484 /// # Platform specific
485 /// On Redox this always returns `None`.
486 #[stable(feature = "unix_socket", since = "1.10.0")]
487 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
488 self.0.take_error()
489 }
490
491 /// Shuts down the read, write, or both halves of this connection.
492 ///
493 /// This function will cause all pending and future I/O calls on the
494 /// specified portions to immediately return with an appropriate value
495 /// (see the documentation of [`Shutdown`]).
496 ///
497 /// # Examples
498 ///
499 #[cfg_attr(target_family = "unix", doc = "```no_run")]
500 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
501 /// use std::os::unix::net::UnixStream;
502 /// use std::net::Shutdown;
503 ///
504 /// fn main() -> std::io::Result<()> {
505 /// let socket = UnixStream::connect("/tmp/sock")?;
506 /// socket.shutdown(Shutdown::Both).expect("`UnixStream::shutdown` should not fail");
507 /// Ok(())
508 /// }
509 /// ```
510 #[stable(feature = "unix_socket", since = "1.10.0")]
511 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
512 self.0.shutdown(how)
513 }
514
515 /// Receives data on the socket from the remote address to which it is
516 /// connected, without removing that data from the queue. On success,
517 /// returns the number of bytes peeked.
518 ///
519 /// Successive calls return the same data. This is accomplished by passing
520 /// `MSG_PEEK` as a flag to the underlying `recv` system call.
521 ///
522 /// # Examples
523 ///
524 #[cfg_attr(target_family = "unix", doc = "```no_run")]
525 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
526 /// #![feature(unix_socket_peek)]
527 ///
528 /// use std::os::unix::net::UnixStream;
529 ///
530 /// fn main() -> std::io::Result<()> {
531 /// let socket = UnixStream::connect("/tmp/sock")?;
532 /// let mut buf = [0; 10];
533 /// let len = socket.peek(&mut buf).expect("`UnixStream::peek` should not fail");
534 /// Ok(())
535 /// }
536 /// ```
537 #[unstable(feature = "unix_socket_peek", issue = "76923")]
538 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
539 self.0.peek(buf)
540 }
541
542 /// Receives data and ancillary data from socket.
543 ///
544 /// On success, returns the number of bytes read.
545 ///
546 /// # Examples
547 ///
548 #[cfg_attr(
549 any(target_os = "android", target_os = "linux", target_os = "cygwin"),
550 doc = "```no_run"
551 )]
552 #[cfg_attr(
553 not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
554 doc = "```ignore"
555 )]
556 /// #![feature(unix_socket_ancillary_data)]
557 /// use std::os::unix::net::{UnixStream, SocketAncillary, AncillaryData};
558 /// use std::io::IoSliceMut;
559 ///
560 /// fn main() -> std::io::Result<()> {
561 /// let socket = UnixStream::connect("/tmp/sock")?;
562 /// let mut buf1 = [1; 8];
563 /// let mut buf2 = [2; 16];
564 /// let mut buf3 = [3; 8];
565 /// let mut bufs = &mut [
566 /// IoSliceMut::new(&mut buf1),
567 /// IoSliceMut::new(&mut buf2),
568 /// IoSliceMut::new(&mut buf3),
569 /// ][..];
570 /// let mut fds = [0; 8];
571 /// let mut ancillary_buffer = [0; 128];
572 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
573 /// let size = socket.recv_vectored_with_ancillary(bufs, &mut ancillary)?;
574 /// println!("received {size}");
575 /// for ancillary_result in ancillary.messages() {
576 /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
577 /// for fd in scm_rights {
578 /// println!("receive file descriptor: {fd}");
579 /// }
580 /// }
581 /// }
582 /// Ok(())
583 /// }
584 /// ```
585 #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
586 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
587 pub fn recv_vectored_with_ancillary(
588 &self,
589 bufs: &mut [IoSliceMut<'_>],
590 ancillary: &mut SocketAncillary<'_>,
591 ) -> io::Result<usize> {
592 let (count, _, _) = recv_vectored_with_ancillary_from(&self.0, bufs, ancillary)?;
593
594 Ok(count)
595 }
596
597 /// Sends data and ancillary data on the socket.
598 ///
599 /// On success, returns the number of bytes written.
600 ///
601 /// # Examples
602 ///
603 #[cfg_attr(
604 any(target_os = "android", target_os = "linux", target_os = "cygwin"),
605 doc = "```no_run"
606 )]
607 #[cfg_attr(
608 not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
609 doc = "```ignore"
610 )]
611 /// #![feature(unix_socket_ancillary_data)]
612 /// use std::os::unix::net::{UnixStream, SocketAncillary};
613 /// use std::io::IoSlice;
614 ///
615 /// fn main() -> std::io::Result<()> {
616 /// let socket = UnixStream::connect("/tmp/sock")?;
617 /// let buf1 = [1; 8];
618 /// let buf2 = [2; 16];
619 /// let buf3 = [3; 8];
620 /// let bufs = &[
621 /// IoSlice::new(&buf1),
622 /// IoSlice::new(&buf2),
623 /// IoSlice::new(&buf3),
624 /// ][..];
625 /// let fds = [0, 1, 2];
626 /// let mut ancillary_buffer = [0; 128];
627 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
628 /// ancillary.add_fds(&fds[..]);
629 /// socket.send_vectored_with_ancillary(bufs, &mut ancillary)
630 /// .expect("send_vectored_with_ancillary function failed");
631 /// Ok(())
632 /// }
633 /// ```
634 #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
635 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
636 pub fn send_vectored_with_ancillary(
637 &self,
638 bufs: &[IoSlice<'_>],
639 ancillary: &mut SocketAncillary<'_>,
640 ) -> io::Result<usize> {
641 send_vectored_with_ancillary_to(&self.0, None, bufs, ancillary)
642 }
643}
644
645#[stable(feature = "unix_socket", since = "1.10.0")]
646impl io::Read for UnixStream {
647 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
648 io::Read::read(&mut &*self, buf)
649 }
650
651 fn read_buf(&mut self, buf: io::BorrowedCursor<'_, u8>) -> io::Result<()> {
652 io::Read::read_buf(&mut &*self, buf)
653 }
654
655 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
656 io::Read::read_vectored(&mut &*self, bufs)
657 }
658
659 #[inline]
660 fn is_read_vectored(&self) -> bool {
661 io::Read::is_read_vectored(&self)
662 }
663}
664
665#[stable(feature = "unix_socket", since = "1.10.0")]
666impl<'a> io::Read for &'a UnixStream {
667 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
668 self.0.read(buf)
669 }
670
671 fn read_buf(&mut self, buf: io::BorrowedCursor<'_, u8>) -> io::Result<()> {
672 self.0.read_buf(buf)
673 }
674
675 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
676 self.0.read_vectored(bufs)
677 }
678
679 #[inline]
680 fn is_read_vectored(&self) -> bool {
681 self.0.is_read_vectored()
682 }
683}
684
685#[stable(feature = "unix_socket", since = "1.10.0")]
686impl io::Write for UnixStream {
687 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
688 io::Write::write(&mut &*self, buf)
689 }
690
691 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
692 io::Write::write_vectored(&mut &*self, bufs)
693 }
694
695 #[inline]
696 fn is_write_vectored(&self) -> bool {
697 io::Write::is_write_vectored(&self)
698 }
699
700 fn flush(&mut self) -> io::Result<()> {
701 io::Write::flush(&mut &*self)
702 }
703}
704
705#[stable(feature = "unix_socket", since = "1.10.0")]
706impl<'a> io::Write for &'a UnixStream {
707 #[rustdoc_skip_body]
708 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
709 self.0.send_with_flags(buf, MSG_NOSIGNAL)
710 }
711
712 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
713 self.0.write_vectored(bufs)
714 }
715
716 #[inline]
717 fn is_write_vectored(&self) -> bool {
718 self.0.is_write_vectored()
719 }
720
721 #[inline]
722 fn flush(&mut self) -> io::Result<()> {
723 Ok(())
724 }
725}
726
727#[stable(feature = "unix_socket", since = "1.10.0")]
728impl AsRawFd for UnixStream {
729 #[inline]
730 #[rustdoc_skip_body]
731 fn as_raw_fd(&self) -> RawFd {
732 self.0.as_raw_fd()
733 }
734}
735
736#[stable(feature = "unix_socket", since = "1.10.0")]
737impl FromRawFd for UnixStream {
738 #[inline]
739 #[rustdoc_skip_body]
740 unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
741 UnixStream(Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd))))
742 }
743}
744
745#[stable(feature = "unix_socket", since = "1.10.0")]
746impl IntoRawFd for UnixStream {
747 #[inline]
748 #[rustdoc_skip_body]
749 fn into_raw_fd(self) -> RawFd {
750 self.0.into_raw_fd()
751 }
752}
753
754#[stable(feature = "io_safety", since = "1.63.0")]
755impl AsFd for UnixStream {
756 #[inline]
757 #[rustdoc_skip_body]
758 fn as_fd(&self) -> BorrowedFd<'_> {
759 self.0.as_fd()
760 }
761}
762
763// SAFETY: It's a tower of 1-field wrappers around OwnedFd.
764// No methods to close the socket, no methods with safety preconditions,
765// other than the fd being valid.
766unsafe_impl_fd_asrefs!(UnixStream);
767
768#[stable(feature = "io_safety", since = "1.63.0")]
769impl From<UnixStream> for OwnedFd {
770 /// Takes ownership of a [`UnixStream`]'s socket file descriptor.
771 #[inline]
772 fn from(unix_stream: UnixStream) -> OwnedFd {
773 unsafe { OwnedFd::from_raw_fd(unix_stream.into_raw_fd()) }
774 }
775}
776
777#[stable(feature = "io_safety", since = "1.63.0")]
778impl From<OwnedFd> for UnixStream {
779 #[inline]
780 fn from(owned: OwnedFd) -> Self {
781 unsafe { Self::from_raw_fd(owned.into_raw_fd()) }
782 }
783}
784
785impl AsInner<Socket> for UnixStream {
786 #[inline]
787 fn as_inner(&self) -> &Socket {
788 &self.0
789 }
790}