std/os/unix/net/
stream.rs

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