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