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