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