1 #[cfg(any(doc, target_os = "android", target_os = "linux"))]
2 use super::{recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to, SocketAncillary};
3 use super::{sockaddr_un, SocketAddr};
5 use crate::io::{self, IoSlice, IoSliceMut};
6 use crate::net::Shutdown;
7 use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
11 target_os = "dragonfly",
12 target_os = "freebsd",
18 use crate::os::unix::ucred;
19 use crate::path::Path;
21 use crate::sys::net::Socket;
22 use crate::sys_common::{AsInner, FromInner};
23 use crate::time::Duration;
25 #[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")]
27 target_os = "android",
29 target_os = "dragonfly",
30 target_os = "freebsd",
38 /// A Unix stream socket.
43 /// use std::os::unix::net::UnixStream;
44 /// use std::io::prelude::*;
46 /// fn main() -> std::io::Result<()> {
47 /// let mut stream = UnixStream::connect("/path/to/my/socket")?;
48 /// stream.write_all(b"hello world")?;
49 /// let mut response = String::new();
50 /// stream.read_to_string(&mut response)?;
51 /// println!("{response}");
55 #[stable(feature = "unix_socket", since = "1.10.0")]
56 pub struct UnixStream(pub(super) Socket);
58 #[stable(feature = "unix_socket", since = "1.10.0")]
59 impl fmt::Debug for UnixStream {
60 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
61 let mut builder = fmt.debug_struct("UnixStream");
62 builder.field("fd", self.0.as_inner());
63 if let Ok(addr) = self.local_addr() {
64 builder.field("local", &addr);
66 if let Ok(addr) = self.peer_addr() {
67 builder.field("peer", &addr);
74 /// Connects to the socket named by `path`.
79 /// use std::os::unix::net::UnixStream;
81 /// let socket = match UnixStream::connect("/tmp/sock") {
84 /// println!("Couldn't connect: {e:?}");
89 #[stable(feature = "unix_socket", since = "1.10.0")]
90 pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
92 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
93 let (addr, len) = sockaddr_un(path.as_ref())?;
95 cvt(libc::connect(inner.as_raw_fd(), &addr as *const _ as *const _, len))?;
100 /// Connects to the socket specified by [`address`].
102 /// [`address`]: crate::os::unix::net::SocketAddr
107 /// #![feature(unix_socket_abstract)]
108 /// use std::os::unix::net::{UnixListener, UnixStream};
110 /// fn main() -> std::io::Result<()> {
111 /// let listener = UnixListener::bind("/path/to/the/socket")?;
112 /// let addr = listener.local_addr()?;
114 /// let sock = match UnixStream::connect_addr(&addr) {
115 /// Ok(sock) => sock,
117 /// println!("Couldn't connect: {e:?}");
124 #[unstable(feature = "unix_socket_abstract", issue = "85410")]
125 pub fn connect_addr(socket_addr: &SocketAddr) -> io::Result<UnixStream> {
127 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
130 &socket_addr.addr as *const _ as *const _,
133 Ok(UnixStream(inner))
137 /// Creates an unnamed pair of connected sockets.
139 /// Returns two `UnixStream`s which are connected to each other.
144 /// use std::os::unix::net::UnixStream;
146 /// let (sock1, sock2) = match UnixStream::pair() {
147 /// Ok((sock1, sock2)) => (sock1, sock2),
149 /// println!("Couldn't create a pair of sockets: {e:?}");
154 #[stable(feature = "unix_socket", since = "1.10.0")]
155 pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
156 let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
157 Ok((UnixStream(i1), UnixStream(i2)))
160 /// Creates a new independently owned handle to the underlying socket.
162 /// The returned `UnixStream` is a reference to the same stream that this
163 /// object references. Both handles will read and write the same stream of
164 /// data, and options set on one stream will be propagated to the other
170 /// use std::os::unix::net::UnixStream;
172 /// fn main() -> std::io::Result<()> {
173 /// let socket = UnixStream::connect("/tmp/sock")?;
174 /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
178 #[stable(feature = "unix_socket", since = "1.10.0")]
179 pub fn try_clone(&self) -> io::Result<UnixStream> {
180 self.0.duplicate().map(UnixStream)
183 /// Returns the socket address of the local half of this connection.
188 /// use std::os::unix::net::UnixStream;
190 /// fn main() -> std::io::Result<()> {
191 /// let socket = UnixStream::connect("/tmp/sock")?;
192 /// let addr = socket.local_addr().expect("Couldn't get local address");
196 #[stable(feature = "unix_socket", since = "1.10.0")]
197 pub fn local_addr(&self) -> io::Result<SocketAddr> {
198 SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.as_raw_fd(), addr, len) })
201 /// Returns the socket address of the remote half of this connection.
206 /// use std::os::unix::net::UnixStream;
208 /// fn main() -> std::io::Result<()> {
209 /// let socket = UnixStream::connect("/tmp/sock")?;
210 /// let addr = socket.peer_addr().expect("Couldn't get peer address");
214 #[stable(feature = "unix_socket", since = "1.10.0")]
215 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
216 SocketAddr::new(|addr, len| unsafe { libc::getpeername(self.as_raw_fd(), addr, len) })
219 /// Gets the peer credentials for this Unix domain socket.
224 /// #![feature(peer_credentials_unix_socket)]
225 /// use std::os::unix::net::UnixStream;
227 /// fn main() -> std::io::Result<()> {
228 /// let socket = UnixStream::connect("/tmp/sock")?;
229 /// let peer_cred = socket.peer_cred().expect("Couldn't get peer credentials");
233 #[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")]
235 target_os = "android",
237 target_os = "dragonfly",
238 target_os = "freebsd",
241 target_os = "netbsd",
242 target_os = "openbsd"
244 pub fn peer_cred(&self) -> io::Result<UCred> {
245 ucred::peer_cred(self)
248 /// Sets the read timeout for the socket.
250 /// If the provided value is [`None`], then [`read`] calls will block
251 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
254 /// [`read`]: io::Read::read
259 /// use std::os::unix::net::UnixStream;
260 /// use std::time::Duration;
262 /// fn main() -> std::io::Result<()> {
263 /// let socket = UnixStream::connect("/tmp/sock")?;
264 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
269 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
274 /// use std::os::unix::net::UnixStream;
275 /// use std::time::Duration;
277 /// fn main() -> std::io::Result<()> {
278 /// let socket = UnixStream::connect("/tmp/sock")?;
279 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
280 /// let err = result.unwrap_err();
281 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
285 #[stable(feature = "unix_socket", since = "1.10.0")]
286 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
287 self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
290 /// Sets the write timeout for the socket.
292 /// If the provided value is [`None`], then [`write`] calls will block
293 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
294 /// passed to this method.
296 /// [`read`]: io::Read::read
301 /// use std::os::unix::net::UnixStream;
302 /// use std::time::Duration;
304 /// fn main() -> std::io::Result<()> {
305 /// let socket = UnixStream::connect("/tmp/sock")?;
306 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
307 /// .expect("Couldn't set write timeout");
312 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
317 /// use std::net::UdpSocket;
318 /// use std::time::Duration;
320 /// fn main() -> std::io::Result<()> {
321 /// let socket = UdpSocket::bind("127.0.0.1:34254")?;
322 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
323 /// let err = result.unwrap_err();
324 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
328 #[stable(feature = "unix_socket", since = "1.10.0")]
329 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
330 self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
333 /// Returns the read timeout of this socket.
338 /// use std::os::unix::net::UnixStream;
339 /// use std::time::Duration;
341 /// fn main() -> std::io::Result<()> {
342 /// let socket = UnixStream::connect("/tmp/sock")?;
343 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
344 /// assert_eq!(socket.read_timeout()?, Some(Duration::new(1, 0)));
348 #[stable(feature = "unix_socket", since = "1.10.0")]
349 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
350 self.0.timeout(libc::SO_RCVTIMEO)
353 /// Returns the write timeout of this socket.
358 /// use std::os::unix::net::UnixStream;
359 /// use std::time::Duration;
361 /// fn main() -> std::io::Result<()> {
362 /// let socket = UnixStream::connect("/tmp/sock")?;
363 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
364 /// .expect("Couldn't set write timeout");
365 /// assert_eq!(socket.write_timeout()?, Some(Duration::new(1, 0)));
369 #[stable(feature = "unix_socket", since = "1.10.0")]
370 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
371 self.0.timeout(libc::SO_SNDTIMEO)
374 /// Moves the socket into or out of nonblocking mode.
379 /// use std::os::unix::net::UnixStream;
381 /// fn main() -> std::io::Result<()> {
382 /// let socket = UnixStream::connect("/tmp/sock")?;
383 /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
387 #[stable(feature = "unix_socket", since = "1.10.0")]
388 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
389 self.0.set_nonblocking(nonblocking)
392 /// Moves the socket to pass unix credentials as control message in [`SocketAncillary`].
394 /// Set the socket option `SO_PASSCRED`.
398 #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
399 #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
400 /// #![feature(unix_socket_ancillary_data)]
401 /// use std::os::unix::net::UnixStream;
403 /// fn main() -> std::io::Result<()> {
404 /// let socket = UnixStream::connect("/tmp/sock")?;
405 /// socket.set_passcred(true).expect("Couldn't set passcred");
409 #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
410 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
411 pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
412 self.0.set_passcred(passcred)
415 /// Get the current value of the socket for passing unix credentials in [`SocketAncillary`].
416 /// This value can be change by [`set_passcred`].
418 /// Get the socket option `SO_PASSCRED`.
420 /// [`set_passcred`]: UnixStream::set_passcred
421 #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
422 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
423 pub fn passcred(&self) -> io::Result<bool> {
427 /// Returns the value of the `SO_ERROR` option.
432 /// use std::os::unix::net::UnixStream;
434 /// fn main() -> std::io::Result<()> {
435 /// let socket = UnixStream::connect("/tmp/sock")?;
436 /// if let Ok(Some(err)) = socket.take_error() {
437 /// println!("Got error: {err:?}");
443 /// # Platform specific
444 /// On Redox this always returns `None`.
445 #[stable(feature = "unix_socket", since = "1.10.0")]
446 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
450 /// Shuts down the read, write, or both halves of this connection.
452 /// This function will cause all pending and future I/O calls on the
453 /// specified portions to immediately return with an appropriate value
454 /// (see the documentation of [`Shutdown`]).
459 /// use std::os::unix::net::UnixStream;
460 /// use std::net::Shutdown;
462 /// fn main() -> std::io::Result<()> {
463 /// let socket = UnixStream::connect("/tmp/sock")?;
464 /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
468 #[stable(feature = "unix_socket", since = "1.10.0")]
469 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
473 /// Receives data on the socket from the remote address to which it is
474 /// connected, without removing that data from the queue. On success,
475 /// returns the number of bytes peeked.
477 /// Successive calls return the same data. This is accomplished by passing
478 /// `MSG_PEEK` as a flag to the underlying `recv` system call.
483 /// #![feature(unix_socket_peek)]
485 /// use std::os::unix::net::UnixStream;
487 /// fn main() -> std::io::Result<()> {
488 /// let socket = UnixStream::connect("/tmp/sock")?;
489 /// let mut buf = [0; 10];
490 /// let len = socket.peek(&mut buf).expect("peek failed");
494 #[unstable(feature = "unix_socket_peek", issue = "76923")]
495 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
499 /// Receives data and ancillary data from socket.
501 /// On success, returns the number of bytes read.
505 #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
506 #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
507 /// #![feature(unix_socket_ancillary_data)]
508 /// use std::os::unix::net::{UnixStream, SocketAncillary, AncillaryData};
509 /// use std::io::IoSliceMut;
511 /// fn main() -> std::io::Result<()> {
512 /// let socket = UnixStream::connect("/tmp/sock")?;
513 /// let mut buf1 = [1; 8];
514 /// let mut buf2 = [2; 16];
515 /// let mut buf3 = [3; 8];
516 /// let mut bufs = &mut [
517 /// IoSliceMut::new(&mut buf1),
518 /// IoSliceMut::new(&mut buf2),
519 /// IoSliceMut::new(&mut buf3),
521 /// let mut fds = [0; 8];
522 /// let mut ancillary_buffer = [0; 128];
523 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
524 /// let size = socket.recv_vectored_with_ancillary(bufs, &mut ancillary)?;
525 /// println!("received {size}");
526 /// for ancillary_result in ancillary.messages() {
527 /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
528 /// for fd in scm_rights {
529 /// println!("receive file descriptor: {fd}");
536 #[cfg(any(doc, target_os = "android", target_os = "linux"))]
537 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
538 pub fn recv_vectored_with_ancillary(
540 bufs: &mut [IoSliceMut<'_>],
541 ancillary: &mut SocketAncillary<'_>,
542 ) -> io::Result<usize> {
543 let (count, _, _) = recv_vectored_with_ancillary_from(&self.0, bufs, ancillary)?;
548 /// Sends data and ancillary data on the socket.
550 /// On success, returns the number of bytes written.
554 #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
555 #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
556 /// #![feature(unix_socket_ancillary_data)]
557 /// use std::os::unix::net::{UnixStream, SocketAncillary};
558 /// use std::io::IoSlice;
560 /// fn main() -> std::io::Result<()> {
561 /// let socket = UnixStream::connect("/tmp/sock")?;
562 /// let buf1 = [1; 8];
563 /// let buf2 = [2; 16];
564 /// let buf3 = [3; 8];
566 /// IoSlice::new(&buf1),
567 /// IoSlice::new(&buf2),
568 /// IoSlice::new(&buf3),
570 /// let fds = [0, 1, 2];
571 /// let mut ancillary_buffer = [0; 128];
572 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
573 /// ancillary.add_fds(&fds[..]);
574 /// socket.send_vectored_with_ancillary(bufs, &mut ancillary)
575 /// .expect("send_vectored_with_ancillary function failed");
579 #[cfg(any(doc, target_os = "android", target_os = "linux"))]
580 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
581 pub fn send_vectored_with_ancillary(
583 bufs: &[IoSlice<'_>],
584 ancillary: &mut SocketAncillary<'_>,
585 ) -> io::Result<usize> {
586 send_vectored_with_ancillary_to(&self.0, None, bufs, ancillary)
590 #[stable(feature = "unix_socket", since = "1.10.0")]
591 impl io::Read for UnixStream {
592 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
593 io::Read::read(&mut &*self, buf)
596 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
597 io::Read::read_vectored(&mut &*self, bufs)
601 fn is_read_vectored(&self) -> bool {
602 io::Read::is_read_vectored(&&*self)
606 #[stable(feature = "unix_socket", since = "1.10.0")]
607 impl<'a> io::Read for &'a UnixStream {
608 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
612 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
613 self.0.read_vectored(bufs)
617 fn is_read_vectored(&self) -> bool {
618 self.0.is_read_vectored()
622 #[stable(feature = "unix_socket", since = "1.10.0")]
623 impl io::Write for UnixStream {
624 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
625 io::Write::write(&mut &*self, buf)
628 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
629 io::Write::write_vectored(&mut &*self, bufs)
633 fn is_write_vectored(&self) -> bool {
634 io::Write::is_write_vectored(&&*self)
637 fn flush(&mut self) -> io::Result<()> {
638 io::Write::flush(&mut &*self)
642 #[stable(feature = "unix_socket", since = "1.10.0")]
643 impl<'a> io::Write for &'a UnixStream {
644 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
648 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
649 self.0.write_vectored(bufs)
653 fn is_write_vectored(&self) -> bool {
654 self.0.is_write_vectored()
657 fn flush(&mut self) -> io::Result<()> {
662 #[stable(feature = "unix_socket", since = "1.10.0")]
663 impl AsRawFd for UnixStream {
665 fn as_raw_fd(&self) -> RawFd {
670 #[stable(feature = "unix_socket", since = "1.10.0")]
671 impl FromRawFd for UnixStream {
673 unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
674 UnixStream(Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd))))
678 #[stable(feature = "unix_socket", since = "1.10.0")]
679 impl IntoRawFd for UnixStream {
681 fn into_raw_fd(self) -> RawFd {
686 #[stable(feature = "io_safety", since = "1.63.0")]
687 impl AsFd for UnixStream {
689 fn as_fd(&self) -> BorrowedFd<'_> {
694 #[stable(feature = "io_safety", since = "1.63.0")]
695 impl From<UnixStream> for OwnedFd {
697 fn from(unix_stream: UnixStream) -> OwnedFd {
698 unsafe { OwnedFd::from_raw_fd(unix_stream.into_raw_fd()) }
702 #[stable(feature = "io_safety", since = "1.63.0")]
703 impl From<OwnedFd> for UnixStream {
705 fn from(owned: OwnedFd) -> Self {
706 unsafe { Self::from_raw_fd(owned.into_raw_fd()) }