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