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}