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