[go: up one dir, main page]

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