Skip to main content

std/os/unix/net/
stream.rs

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