Skip to main content

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}