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