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