1 //! Unix-specific networking functionality.
3 #![stable(feature = "unix_socket", since = "1.10.0")]
5 #[cfg(all(test, not(target_os = "emscripten")))]
8 // FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here?
10 #[allow(non_camel_case_types)]
13 pub type socklen_t = u32;
16 pub struct sockaddr_un;
20 use crate::ffi::OsStr;
22 use crate::io::{self, Initializer, IoSlice, IoSliceMut};
24 use crate::net::{self, Shutdown};
25 use crate::os::unix::ffi::OsStrExt;
26 use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
27 use crate::path::Path;
28 use crate::sys::net::Socket;
29 use crate::sys::{self, cvt};
30 use crate::sys_common::{self, AsInner, FromInner, IntoInner};
31 use crate::time::Duration;
35 target_os = "android",
36 target_os = "dragonfly",
37 target_os = "freebsd",
38 target_os = "openbsd",
42 use libc::MSG_NOSIGNAL;
45 target_os = "android",
46 target_os = "dragonfly",
47 target_os = "freebsd",
48 target_os = "openbsd",
52 const MSG_NOSIGNAL: libc::c_int = 0x0;
54 fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
55 // Work with an actual instance of the type since using a null pointer is UB
56 let base = addr as *const _ as usize;
57 let path = &addr.sun_path as *const _ as usize;
61 unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::socklen_t)> {
62 let mut addr: libc::sockaddr_un = mem::zeroed();
63 addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
65 let bytes = path.as_os_str().as_bytes();
67 if bytes.contains(&0) {
68 return Err(io::Error::new(
69 io::ErrorKind::InvalidInput,
70 "paths may not contain interior null bytes",
74 if bytes.len() >= addr.sun_path.len() {
75 return Err(io::Error::new(
76 io::ErrorKind::InvalidInput,
77 "path must be shorter than SUN_LEN",
80 for (dst, src) in addr.sun_path.iter_mut().zip(bytes.iter()) {
81 *dst = *src as libc::c_char;
83 // null byte for pathname addresses is already there because we zeroed the
86 let mut len = sun_path_offset(&addr) + bytes.len();
91 Ok((addr, len as libc::socklen_t))
94 enum AddressKind<'a> {
100 /// An address associated with a Unix socket.
105 /// use std::os::unix::net::UnixListener;
107 /// let socket = match UnixListener::bind("/tmp/sock") {
108 /// Ok(sock) => sock,
110 /// println!("Couldn't bind: {:?}", e);
114 /// let addr = socket.local_addr().expect("Couldn't get local address");
117 #[stable(feature = "unix_socket", since = "1.10.0")]
118 pub struct SocketAddr {
119 addr: libc::sockaddr_un,
120 len: libc::socklen_t,
124 fn new<F>(f: F) -> io::Result<SocketAddr>
126 F: FnOnce(*mut libc::sockaddr, *mut libc::socklen_t) -> libc::c_int,
129 let mut addr: libc::sockaddr_un = mem::zeroed();
130 let mut len = mem::size_of::<libc::sockaddr_un>() as libc::socklen_t;
131 cvt(f(&mut addr as *mut _ as *mut _, &mut len))?;
132 SocketAddr::from_parts(addr, len)
136 fn from_parts(addr: libc::sockaddr_un, mut len: libc::socklen_t) -> io::Result<SocketAddr> {
138 // When there is a datagram from unnamed unix socket
139 // linux returns zero bytes of address
140 len = sun_path_offset(&addr) as libc::socklen_t; // i.e., zero-length address
141 } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
142 return Err(io::Error::new(
143 io::ErrorKind::InvalidInput,
144 "file descriptor did not correspond to a Unix socket",
148 Ok(SocketAddr { addr, len })
151 /// Returns `true` if the address is unnamed.
158 /// use std::os::unix::net::UnixListener;
160 /// fn main() -> std::io::Result<()> {
161 /// let socket = UnixListener::bind("/tmp/sock")?;
162 /// let addr = socket.local_addr().expect("Couldn't get local address");
163 /// assert_eq!(addr.is_unnamed(), false);
168 /// An unnamed address:
171 /// use std::os::unix::net::UnixDatagram;
173 /// fn main() -> std::io::Result<()> {
174 /// let socket = UnixDatagram::unbound()?;
175 /// let addr = socket.local_addr().expect("Couldn't get local address");
176 /// assert_eq!(addr.is_unnamed(), true);
180 #[stable(feature = "unix_socket", since = "1.10.0")]
181 pub fn is_unnamed(&self) -> bool {
182 if let AddressKind::Unnamed = self.address() { true } else { false }
185 /// Returns the contents of this address if it is a `pathname` address.
192 /// use std::os::unix::net::UnixListener;
193 /// use std::path::Path;
195 /// fn main() -> std::io::Result<()> {
196 /// let socket = UnixListener::bind("/tmp/sock")?;
197 /// let addr = socket.local_addr().expect("Couldn't get local address");
198 /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock")));
203 /// Without a pathname:
206 /// use std::os::unix::net::UnixDatagram;
208 /// fn main() -> std::io::Result<()> {
209 /// let socket = UnixDatagram::unbound()?;
210 /// let addr = socket.local_addr().expect("Couldn't get local address");
211 /// assert_eq!(addr.as_pathname(), None);
215 #[stable(feature = "unix_socket", since = "1.10.0")]
216 pub fn as_pathname(&self) -> Option<&Path> {
217 if let AddressKind::Pathname(path) = self.address() { Some(path) } else { None }
220 fn address(&self) -> AddressKind<'_> {
221 let len = self.len as usize - sun_path_offset(&self.addr);
222 let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
224 // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
226 || (cfg!(not(any(target_os = "linux", target_os = "android")))
227 && self.addr.sun_path[0] == 0)
230 } else if self.addr.sun_path[0] == 0 {
231 AddressKind::Abstract(&path[1..len])
233 AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref())
238 #[stable(feature = "unix_socket", since = "1.10.0")]
239 impl fmt::Debug for SocketAddr {
240 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
241 match self.address() {
242 AddressKind::Unnamed => write!(fmt, "(unnamed)"),
243 AddressKind::Abstract(name) => write!(fmt, "{} (abstract)", AsciiEscaped(name)),
244 AddressKind::Pathname(path) => write!(fmt, "{:?} (pathname)", path),
249 struct AsciiEscaped<'a>(&'a [u8]);
251 impl<'a> fmt::Display for AsciiEscaped<'a> {
252 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
254 for byte in self.0.iter().cloned().flat_map(ascii::escape_default) {
255 write!(fmt, "{}", byte as char)?;
261 /// A Unix stream socket.
266 /// use std::os::unix::net::UnixStream;
267 /// use std::io::prelude::*;
269 /// fn main() -> std::io::Result<()> {
270 /// let mut stream = UnixStream::connect("/path/to/my/socket")?;
271 /// stream.write_all(b"hello world")?;
272 /// let mut response = String::new();
273 /// stream.read_to_string(&mut response)?;
274 /// println!("{}", response);
278 #[stable(feature = "unix_socket", since = "1.10.0")]
279 pub struct UnixStream(Socket);
281 #[stable(feature = "unix_socket", since = "1.10.0")]
282 impl fmt::Debug for UnixStream {
283 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
284 let mut builder = fmt.debug_struct("UnixStream");
285 builder.field("fd", self.0.as_inner());
286 if let Ok(addr) = self.local_addr() {
287 builder.field("local", &addr);
289 if let Ok(addr) = self.peer_addr() {
290 builder.field("peer", &addr);
297 /// Connects to the socket named by `path`.
302 /// use std::os::unix::net::UnixStream;
304 /// let socket = match UnixStream::connect("/tmp/sock") {
305 /// Ok(sock) => sock,
307 /// println!("Couldn't connect: {:?}", e);
312 #[stable(feature = "unix_socket", since = "1.10.0")]
313 pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
314 fn inner(path: &Path) -> io::Result<UnixStream> {
316 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
317 let (addr, len) = sockaddr_un(path)?;
319 cvt(libc::connect(*inner.as_inner(), &addr as *const _ as *const _, len))?;
320 Ok(UnixStream(inner))
326 /// Creates an unnamed pair of connected sockets.
328 /// Returns two `UnixStream`s which are connected to each other.
333 /// use std::os::unix::net::UnixStream;
335 /// let (sock1, sock2) = match UnixStream::pair() {
336 /// Ok((sock1, sock2)) => (sock1, sock2),
338 /// println!("Couldn't create a pair of sockets: {:?}", e);
343 #[stable(feature = "unix_socket", since = "1.10.0")]
344 pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
345 let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
346 Ok((UnixStream(i1), UnixStream(i2)))
349 /// Creates a new independently owned handle to the underlying socket.
351 /// The returned `UnixStream` is a reference to the same stream that this
352 /// object references. Both handles will read and write the same stream of
353 /// data, and options set on one stream will be propagated to the other
359 /// use std::os::unix::net::UnixStream;
361 /// fn main() -> std::io::Result<()> {
362 /// let socket = UnixStream::connect("/tmp/sock")?;
363 /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
367 #[stable(feature = "unix_socket", since = "1.10.0")]
368 pub fn try_clone(&self) -> io::Result<UnixStream> {
369 self.0.duplicate().map(UnixStream)
372 /// Returns the socket address of the local half of this connection.
377 /// use std::os::unix::net::UnixStream;
379 /// fn main() -> std::io::Result<()> {
380 /// let socket = UnixStream::connect("/tmp/sock")?;
381 /// let addr = socket.local_addr().expect("Couldn't get local address");
385 #[stable(feature = "unix_socket", since = "1.10.0")]
386 pub fn local_addr(&self) -> io::Result<SocketAddr> {
387 SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
390 /// Returns the socket address of the remote half of this connection.
395 /// use std::os::unix::net::UnixStream;
397 /// fn main() -> std::io::Result<()> {
398 /// let socket = UnixStream::connect("/tmp/sock")?;
399 /// let addr = socket.peer_addr().expect("Couldn't get peer address");
403 #[stable(feature = "unix_socket", since = "1.10.0")]
404 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
405 SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
408 /// Sets the read timeout for the socket.
410 /// If the provided value is [`None`], then [`read`] calls will block
411 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
414 /// [`read`]: io::Read::read
419 /// use std::os::unix::net::UnixStream;
420 /// use std::time::Duration;
422 /// fn main() -> std::io::Result<()> {
423 /// let socket = UnixStream::connect("/tmp/sock")?;
424 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
429 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
434 /// use std::os::unix::net::UnixStream;
435 /// use std::time::Duration;
437 /// fn main() -> std::io::Result<()> {
438 /// let socket = UnixStream::connect("/tmp/sock")?;
439 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
440 /// let err = result.unwrap_err();
441 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
445 #[stable(feature = "unix_socket", since = "1.10.0")]
446 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
447 self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
450 /// Sets the write timeout for the socket.
452 /// If the provided value is [`None`], then [`write`] calls will block
453 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
454 /// passed to this method.
456 /// [`read`]: io::Read::read
461 /// use std::os::unix::net::UnixStream;
462 /// use std::time::Duration;
464 /// fn main() -> std::io::Result<()> {
465 /// let socket = UnixStream::connect("/tmp/sock")?;
466 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
467 /// .expect("Couldn't set write timeout");
472 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
477 /// use std::net::UdpSocket;
478 /// use std::time::Duration;
480 /// fn main() -> std::io::Result<()> {
481 /// let socket = UdpSocket::bind("127.0.0.1:34254")?;
482 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
483 /// let err = result.unwrap_err();
484 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
488 #[stable(feature = "unix_socket", since = "1.10.0")]
489 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
490 self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
493 /// Returns the read timeout of this socket.
498 /// use std::os::unix::net::UnixStream;
499 /// use std::time::Duration;
501 /// fn main() -> std::io::Result<()> {
502 /// let socket = UnixStream::connect("/tmp/sock")?;
503 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
504 /// assert_eq!(socket.read_timeout()?, Some(Duration::new(1, 0)));
508 #[stable(feature = "unix_socket", since = "1.10.0")]
509 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
510 self.0.timeout(libc::SO_RCVTIMEO)
513 /// Returns the write timeout of this socket.
518 /// use std::os::unix::net::UnixStream;
519 /// use std::time::Duration;
521 /// fn main() -> std::io::Result<()> {
522 /// let socket = UnixStream::connect("/tmp/sock")?;
523 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
524 /// .expect("Couldn't set write timeout");
525 /// assert_eq!(socket.write_timeout()?, Some(Duration::new(1, 0)));
529 #[stable(feature = "unix_socket", since = "1.10.0")]
530 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
531 self.0.timeout(libc::SO_SNDTIMEO)
534 /// Moves the socket into or out of nonblocking mode.
539 /// use std::os::unix::net::UnixStream;
541 /// fn main() -> std::io::Result<()> {
542 /// let socket = UnixStream::connect("/tmp/sock")?;
543 /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
547 #[stable(feature = "unix_socket", since = "1.10.0")]
548 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
549 self.0.set_nonblocking(nonblocking)
552 /// Returns the value of the `SO_ERROR` option.
557 /// use std::os::unix::net::UnixStream;
559 /// fn main() -> std::io::Result<()> {
560 /// let socket = UnixStream::connect("/tmp/sock")?;
561 /// if let Ok(Some(err)) = socket.take_error() {
562 /// println!("Got error: {:?}", err);
568 /// # Platform specific
569 /// On Redox this always returns `None`.
570 #[stable(feature = "unix_socket", since = "1.10.0")]
571 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
575 /// Shuts down the read, write, or both halves of this connection.
577 /// This function will cause all pending and future I/O calls on the
578 /// specified portions to immediately return with an appropriate value
579 /// (see the documentation of [`Shutdown`]).
584 /// use std::os::unix::net::UnixStream;
585 /// use std::net::Shutdown;
587 /// fn main() -> std::io::Result<()> {
588 /// let socket = UnixStream::connect("/tmp/sock")?;
589 /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
593 #[stable(feature = "unix_socket", since = "1.10.0")]
594 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
598 /// Receives data on the socket from the remote address to which it is
599 /// connected, without removing that data from the queue. On success,
600 /// returns the number of bytes peeked.
602 /// Successive calls return the same data. This is accomplished by passing
603 /// `MSG_PEEK` as a flag to the underlying `recv` system call.
608 /// #![feature(unix_socket_peek)]
610 /// use std::os::unix::net::UnixStream;
612 /// fn main() -> std::io::Result<()> {
613 /// let socket = UnixStream::connect("/tmp/sock")?;
614 /// let mut buf = [0; 10];
615 /// let len = socket.peek(&mut buf).expect("peek failed");
619 #[unstable(feature = "unix_socket_peek", issue = "none")]
620 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
625 #[stable(feature = "unix_socket", since = "1.10.0")]
626 impl io::Read for UnixStream {
627 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
628 io::Read::read(&mut &*self, buf)
631 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
632 io::Read::read_vectored(&mut &*self, bufs)
636 fn is_read_vectored(&self) -> bool {
637 io::Read::is_read_vectored(&&*self)
641 unsafe fn initializer(&self) -> Initializer {
646 #[stable(feature = "unix_socket", since = "1.10.0")]
647 impl<'a> io::Read for &'a UnixStream {
648 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
652 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
653 self.0.read_vectored(bufs)
657 fn is_read_vectored(&self) -> bool {
658 self.0.is_read_vectored()
662 unsafe fn initializer(&self) -> Initializer {
667 #[stable(feature = "unix_socket", since = "1.10.0")]
668 impl io::Write for UnixStream {
669 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
670 io::Write::write(&mut &*self, buf)
673 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
674 io::Write::write_vectored(&mut &*self, bufs)
678 fn is_write_vectored(&self) -> bool {
679 io::Write::is_write_vectored(&&*self)
682 fn flush(&mut self) -> io::Result<()> {
683 io::Write::flush(&mut &*self)
687 #[stable(feature = "unix_socket", since = "1.10.0")]
688 impl<'a> io::Write for &'a UnixStream {
689 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
693 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
694 self.0.write_vectored(bufs)
698 fn is_write_vectored(&self) -> bool {
699 self.0.is_write_vectored()
702 fn flush(&mut self) -> io::Result<()> {
707 #[stable(feature = "unix_socket", since = "1.10.0")]
708 impl AsRawFd for UnixStream {
709 fn as_raw_fd(&self) -> RawFd {
714 #[stable(feature = "unix_socket", since = "1.10.0")]
715 impl FromRawFd for UnixStream {
716 unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
717 UnixStream(Socket::from_inner(fd))
721 #[stable(feature = "unix_socket", since = "1.10.0")]
722 impl IntoRawFd for UnixStream {
723 fn into_raw_fd(self) -> RawFd {
728 #[stable(feature = "rust1", since = "1.0.0")]
729 impl AsRawFd for net::TcpStream {
730 fn as_raw_fd(&self) -> RawFd {
731 *self.as_inner().socket().as_inner()
735 #[stable(feature = "rust1", since = "1.0.0")]
736 impl AsRawFd for net::TcpListener {
737 fn as_raw_fd(&self) -> RawFd {
738 *self.as_inner().socket().as_inner()
742 #[stable(feature = "rust1", since = "1.0.0")]
743 impl AsRawFd for net::UdpSocket {
744 fn as_raw_fd(&self) -> RawFd {
745 *self.as_inner().socket().as_inner()
749 #[stable(feature = "from_raw_os", since = "1.1.0")]
750 impl FromRawFd for net::TcpStream {
751 unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
752 let socket = sys::net::Socket::from_inner(fd);
753 net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(socket))
757 #[stable(feature = "from_raw_os", since = "1.1.0")]
758 impl FromRawFd for net::TcpListener {
759 unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
760 let socket = sys::net::Socket::from_inner(fd);
761 net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(socket))
765 #[stable(feature = "from_raw_os", since = "1.1.0")]
766 impl FromRawFd for net::UdpSocket {
767 unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
768 let socket = sys::net::Socket::from_inner(fd);
769 net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(socket))
773 #[stable(feature = "into_raw_os", since = "1.4.0")]
774 impl IntoRawFd for net::TcpStream {
775 fn into_raw_fd(self) -> RawFd {
776 self.into_inner().into_socket().into_inner()
779 #[stable(feature = "into_raw_os", since = "1.4.0")]
780 impl IntoRawFd for net::TcpListener {
781 fn into_raw_fd(self) -> RawFd {
782 self.into_inner().into_socket().into_inner()
785 #[stable(feature = "into_raw_os", since = "1.4.0")]
786 impl IntoRawFd for net::UdpSocket {
787 fn into_raw_fd(self) -> RawFd {
788 self.into_inner().into_socket().into_inner()
792 /// A structure representing a Unix domain socket server.
798 /// use std::os::unix::net::{UnixStream, UnixListener};
800 /// fn handle_client(stream: UnixStream) {
804 /// fn main() -> std::io::Result<()> {
805 /// let listener = UnixListener::bind("/path/to/the/socket")?;
807 /// // accept connections and process them, spawning a new thread for each one
808 /// for stream in listener.incoming() {
811 /// /* connection succeeded */
812 /// thread::spawn(|| handle_client(stream));
815 /// /* connection failed */
823 #[stable(feature = "unix_socket", since = "1.10.0")]
824 pub struct UnixListener(Socket);
826 #[stable(feature = "unix_socket", since = "1.10.0")]
827 impl fmt::Debug for UnixListener {
828 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
829 let mut builder = fmt.debug_struct("UnixListener");
830 builder.field("fd", self.0.as_inner());
831 if let Ok(addr) = self.local_addr() {
832 builder.field("local", &addr);
839 /// Creates a new `UnixListener` bound to the specified socket.
844 /// use std::os::unix::net::UnixListener;
846 /// let listener = match UnixListener::bind("/path/to/the/socket") {
847 /// Ok(sock) => sock,
849 /// println!("Couldn't connect: {:?}", e);
854 #[stable(feature = "unix_socket", since = "1.10.0")]
855 pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
856 fn inner(path: &Path) -> io::Result<UnixListener> {
858 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
859 let (addr, len) = sockaddr_un(path)?;
861 cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len as _))?;
862 cvt(libc::listen(*inner.as_inner(), 128))?;
864 Ok(UnixListener(inner))
870 /// Accepts a new incoming connection to this listener.
872 /// This function will block the calling thread until a new Unix connection
873 /// is established. When established, the corresponding [`UnixStream`] and
874 /// the remote peer's address will be returned.
876 /// [`UnixStream`]: crate::os::unix::net::UnixStream
881 /// use std::os::unix::net::UnixListener;
883 /// fn main() -> std::io::Result<()> {
884 /// let listener = UnixListener::bind("/path/to/the/socket")?;
886 /// match listener.accept() {
887 /// Ok((socket, addr)) => println!("Got a client: {:?}", addr),
888 /// Err(e) => println!("accept function failed: {:?}", e),
893 #[stable(feature = "unix_socket", since = "1.10.0")]
894 pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
895 let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() };
896 let mut len = mem::size_of_val(&storage) as libc::socklen_t;
897 let sock = self.0.accept(&mut storage as *mut _ as *mut _, &mut len)?;
898 let addr = SocketAddr::from_parts(storage, len)?;
899 Ok((UnixStream(sock), addr))
902 /// Creates a new independently owned handle to the underlying socket.
904 /// The returned `UnixListener` is a reference to the same socket that this
905 /// object references. Both handles can be used to accept incoming
906 /// connections and options set on one listener will affect the other.
911 /// use std::os::unix::net::UnixListener;
913 /// fn main() -> std::io::Result<()> {
914 /// let listener = UnixListener::bind("/path/to/the/socket")?;
915 /// let listener_copy = listener.try_clone().expect("try_clone failed");
919 #[stable(feature = "unix_socket", since = "1.10.0")]
920 pub fn try_clone(&self) -> io::Result<UnixListener> {
921 self.0.duplicate().map(UnixListener)
924 /// Returns the local socket address of this listener.
929 /// use std::os::unix::net::UnixListener;
931 /// fn main() -> std::io::Result<()> {
932 /// let listener = UnixListener::bind("/path/to/the/socket")?;
933 /// let addr = listener.local_addr().expect("Couldn't get local address");
937 #[stable(feature = "unix_socket", since = "1.10.0")]
938 pub fn local_addr(&self) -> io::Result<SocketAddr> {
939 SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
942 /// Moves the socket into or out of nonblocking mode.
944 /// This will result in the `accept` operation becoming nonblocking,
945 /// i.e., immediately returning from their calls. If the IO operation is
946 /// successful, `Ok` is returned and no further action is required. If the
947 /// IO operation could not be completed and needs to be retried, an error
948 /// with kind [`io::ErrorKind::WouldBlock`] is returned.
953 /// use std::os::unix::net::UnixListener;
955 /// fn main() -> std::io::Result<()> {
956 /// let listener = UnixListener::bind("/path/to/the/socket")?;
957 /// listener.set_nonblocking(true).expect("Couldn't set non blocking");
961 #[stable(feature = "unix_socket", since = "1.10.0")]
962 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
963 self.0.set_nonblocking(nonblocking)
966 /// Returns the value of the `SO_ERROR` option.
971 /// use std::os::unix::net::UnixListener;
973 /// fn main() -> std::io::Result<()> {
974 /// let listener = UnixListener::bind("/tmp/sock")?;
976 /// if let Ok(Some(err)) = listener.take_error() {
977 /// println!("Got error: {:?}", err);
983 /// # Platform specific
984 /// On Redox this always returns `None`.
985 #[stable(feature = "unix_socket", since = "1.10.0")]
986 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
990 /// Returns an iterator over incoming connections.
992 /// The iterator will never return [`None`] and will also not yield the
993 /// peer's [`SocketAddr`] structure.
999 /// use std::os::unix::net::{UnixStream, UnixListener};
1001 /// fn handle_client(stream: UnixStream) {
1005 /// fn main() -> std::io::Result<()> {
1006 /// let listener = UnixListener::bind("/path/to/the/socket")?;
1008 /// for stream in listener.incoming() {
1011 /// thread::spawn(|| handle_client(stream));
1021 #[stable(feature = "unix_socket", since = "1.10.0")]
1022 pub fn incoming(&self) -> Incoming<'_> {
1023 Incoming { listener: self }
1027 #[stable(feature = "unix_socket", since = "1.10.0")]
1028 impl AsRawFd for UnixListener {
1029 fn as_raw_fd(&self) -> RawFd {
1034 #[stable(feature = "unix_socket", since = "1.10.0")]
1035 impl FromRawFd for UnixListener {
1036 unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
1037 UnixListener(Socket::from_inner(fd))
1041 #[stable(feature = "unix_socket", since = "1.10.0")]
1042 impl IntoRawFd for UnixListener {
1043 fn into_raw_fd(self) -> RawFd {
1048 #[stable(feature = "unix_socket", since = "1.10.0")]
1049 impl<'a> IntoIterator for &'a UnixListener {
1050 type Item = io::Result<UnixStream>;
1051 type IntoIter = Incoming<'a>;
1053 fn into_iter(self) -> Incoming<'a> {
1058 /// An iterator over incoming connections to a [`UnixListener`].
1060 /// It will never return [`None`].
1065 /// use std::thread;
1066 /// use std::os::unix::net::{UnixStream, UnixListener};
1068 /// fn handle_client(stream: UnixStream) {
1072 /// fn main() -> std::io::Result<()> {
1073 /// let listener = UnixListener::bind("/path/to/the/socket")?;
1075 /// for stream in listener.incoming() {
1078 /// thread::spawn(|| handle_client(stream));
1089 #[stable(feature = "unix_socket", since = "1.10.0")]
1090 pub struct Incoming<'a> {
1091 listener: &'a UnixListener,
1094 #[stable(feature = "unix_socket", since = "1.10.0")]
1095 impl<'a> Iterator for Incoming<'a> {
1096 type Item = io::Result<UnixStream>;
1098 fn next(&mut self) -> Option<io::Result<UnixStream>> {
1099 Some(self.listener.accept().map(|s| s.0))
1102 fn size_hint(&self) -> (usize, Option<usize>) {
1107 /// A Unix datagram socket.
1112 /// use std::os::unix::net::UnixDatagram;
1114 /// fn main() -> std::io::Result<()> {
1115 /// let socket = UnixDatagram::bind("/path/to/my/socket")?;
1116 /// socket.send_to(b"hello world", "/path/to/other/socket")?;
1117 /// let mut buf = [0; 100];
1118 /// let (count, address) = socket.recv_from(&mut buf)?;
1119 /// println!("socket {:?} sent {:?}", address, &buf[..count]);
1123 #[stable(feature = "unix_socket", since = "1.10.0")]
1124 pub struct UnixDatagram(Socket);
1126 #[stable(feature = "unix_socket", since = "1.10.0")]
1127 impl fmt::Debug for UnixDatagram {
1128 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1129 let mut builder = fmt.debug_struct("UnixDatagram");
1130 builder.field("fd", self.0.as_inner());
1131 if let Ok(addr) = self.local_addr() {
1132 builder.field("local", &addr);
1134 if let Ok(addr) = self.peer_addr() {
1135 builder.field("peer", &addr);
1142 /// Creates a Unix datagram socket bound to the given path.
1147 /// use std::os::unix::net::UnixDatagram;
1149 /// let sock = match UnixDatagram::bind("/path/to/the/socket") {
1150 /// Ok(sock) => sock,
1152 /// println!("Couldn't bind: {:?}", e);
1157 #[stable(feature = "unix_socket", since = "1.10.0")]
1158 pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
1159 fn inner(path: &Path) -> io::Result<UnixDatagram> {
1161 let socket = UnixDatagram::unbound()?;
1162 let (addr, len) = sockaddr_un(path)?;
1164 cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len as _))?;
1169 inner(path.as_ref())
1172 /// Creates a Unix Datagram socket which is not bound to any address.
1177 /// use std::os::unix::net::UnixDatagram;
1179 /// let sock = match UnixDatagram::unbound() {
1180 /// Ok(sock) => sock,
1182 /// println!("Couldn't unbound: {:?}", e);
1187 #[stable(feature = "unix_socket", since = "1.10.0")]
1188 pub fn unbound() -> io::Result<UnixDatagram> {
1189 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?;
1190 Ok(UnixDatagram(inner))
1193 /// Creates an unnamed pair of connected sockets.
1195 /// Returns two `UnixDatagrams`s which are connected to each other.
1200 /// use std::os::unix::net::UnixDatagram;
1202 /// let (sock1, sock2) = match UnixDatagram::pair() {
1203 /// Ok((sock1, sock2)) => (sock1, sock2),
1205 /// println!("Couldn't unbound: {:?}", e);
1210 #[stable(feature = "unix_socket", since = "1.10.0")]
1211 pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
1212 let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?;
1213 Ok((UnixDatagram(i1), UnixDatagram(i2)))
1216 /// Connects the socket to the specified address.
1218 /// The [`send`] method may be used to send data to the specified address.
1219 /// [`recv`] and [`recv_from`] will only receive data from that address.
1221 /// [`send`]: UnixDatagram::send
1222 /// [`recv`]: UnixDatagram::recv
1223 /// [`recv_from`]: UnixDatagram::recv_from
1228 /// use std::os::unix::net::UnixDatagram;
1230 /// fn main() -> std::io::Result<()> {
1231 /// let sock = UnixDatagram::unbound()?;
1232 /// match sock.connect("/path/to/the/socket") {
1233 /// Ok(sock) => sock,
1235 /// println!("Couldn't connect: {:?}", e);
1242 #[stable(feature = "unix_socket", since = "1.10.0")]
1243 pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
1244 fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> {
1246 let (addr, len) = sockaddr_un(path)?;
1248 cvt(libc::connect(*d.0.as_inner(), &addr as *const _ as *const _, len))?;
1253 inner(self, path.as_ref())
1256 /// Creates a new independently owned handle to the underlying socket.
1258 /// The returned `UnixDatagram` is a reference to the same socket that this
1259 /// object references. Both handles can be used to accept incoming
1260 /// connections and options set on one side will affect the other.
1265 /// use std::os::unix::net::UnixDatagram;
1267 /// fn main() -> std::io::Result<()> {
1268 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
1269 /// let sock_copy = sock.try_clone().expect("try_clone failed");
1273 #[stable(feature = "unix_socket", since = "1.10.0")]
1274 pub fn try_clone(&self) -> io::Result<UnixDatagram> {
1275 self.0.duplicate().map(UnixDatagram)
1278 /// Returns the address of this socket.
1283 /// use std::os::unix::net::UnixDatagram;
1285 /// fn main() -> std::io::Result<()> {
1286 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
1287 /// let addr = sock.local_addr().expect("Couldn't get local address");
1291 #[stable(feature = "unix_socket", since = "1.10.0")]
1292 pub fn local_addr(&self) -> io::Result<SocketAddr> {
1293 SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
1296 /// Returns the address of this socket's peer.
1298 /// The [`connect`] method will connect the socket to a peer.
1300 /// [`connect`]: UnixDatagram::connect
1305 /// use std::os::unix::net::UnixDatagram;
1307 /// fn main() -> std::io::Result<()> {
1308 /// let sock = UnixDatagram::unbound()?;
1309 /// sock.connect("/path/to/the/socket")?;
1311 /// let addr = sock.peer_addr().expect("Couldn't get peer address");
1315 #[stable(feature = "unix_socket", since = "1.10.0")]
1316 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
1317 SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
1324 ) -> io::Result<(usize, SocketAddr)> {
1326 let addr = SocketAddr::new(|addr, len| unsafe {
1327 count = libc::recvfrom(
1329 buf.as_mut_ptr() as *mut _,
1337 } else if count == 0 {
1344 Ok((count as usize, addr))
1347 /// Receives data from the socket.
1349 /// On success, returns the number of bytes read and the address from
1350 /// whence the data came.
1355 /// use std::os::unix::net::UnixDatagram;
1357 /// fn main() -> std::io::Result<()> {
1358 /// let sock = UnixDatagram::unbound()?;
1359 /// let mut buf = vec![0; 10];
1360 /// let (size, sender) = sock.recv_from(buf.as_mut_slice())?;
1361 /// println!("received {} bytes from {:?}", size, sender);
1365 #[stable(feature = "unix_socket", since = "1.10.0")]
1366 pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
1367 self.recv_from_flags(buf, 0)
1370 /// Receives data from the socket.
1372 /// On success, returns the number of bytes read.
1377 /// use std::os::unix::net::UnixDatagram;
1379 /// fn main() -> std::io::Result<()> {
1380 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
1381 /// let mut buf = vec![0; 10];
1382 /// sock.recv(buf.as_mut_slice()).expect("recv function failed");
1386 #[stable(feature = "unix_socket", since = "1.10.0")]
1387 pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
1391 /// Sends data on the socket to the specified address.
1393 /// On success, returns the number of bytes written.
1398 /// use std::os::unix::net::UnixDatagram;
1400 /// fn main() -> std::io::Result<()> {
1401 /// let sock = UnixDatagram::unbound()?;
1402 /// sock.send_to(b"omelette au fromage", "/some/sock").expect("send_to function failed");
1406 #[stable(feature = "unix_socket", since = "1.10.0")]
1407 pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
1408 fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result<usize> {
1410 let (addr, len) = sockaddr_un(path)?;
1412 let count = cvt(libc::sendto(
1414 buf.as_ptr() as *const _,
1417 &addr as *const _ as *const _,
1423 inner(self, buf, path.as_ref())
1426 /// Sends data on the socket to the socket's peer.
1428 /// The peer address may be set by the `connect` method, and this method
1429 /// will return an error if the socket has not already been connected.
1431 /// On success, returns the number of bytes written.
1436 /// use std::os::unix::net::UnixDatagram;
1438 /// fn main() -> std::io::Result<()> {
1439 /// let sock = UnixDatagram::unbound()?;
1440 /// sock.connect("/some/sock").expect("Couldn't connect");
1441 /// sock.send(b"omelette au fromage").expect("send_to function failed");
1445 #[stable(feature = "unix_socket", since = "1.10.0")]
1446 pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
1450 /// Sets the read timeout for the socket.
1452 /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will
1453 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`]
1454 /// is passed to this method.
1456 /// [`recv`]: UnixDatagram::recv
1457 /// [`recv_from`]: UnixDatagram::recv_from
1462 /// use std::os::unix::net::UnixDatagram;
1463 /// use std::time::Duration;
1465 /// fn main() -> std::io::Result<()> {
1466 /// let sock = UnixDatagram::unbound()?;
1467 /// sock.set_read_timeout(Some(Duration::new(1, 0)))
1468 /// .expect("set_read_timeout function failed");
1473 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
1478 /// use std::os::unix::net::UnixDatagram;
1479 /// use std::time::Duration;
1481 /// fn main() -> std::io::Result<()> {
1482 /// let socket = UnixDatagram::unbound()?;
1483 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
1484 /// let err = result.unwrap_err();
1485 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
1489 #[stable(feature = "unix_socket", since = "1.10.0")]
1490 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
1491 self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
1494 /// Sets the write timeout for the socket.
1496 /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will
1497 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
1500 /// [`send`]: UnixDatagram::send
1501 /// [`send_to`]: UnixDatagram::send_to
1506 /// use std::os::unix::net::UnixDatagram;
1507 /// use std::time::Duration;
1509 /// fn main() -> std::io::Result<()> {
1510 /// let sock = UnixDatagram::unbound()?;
1511 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
1512 /// .expect("set_write_timeout function failed");
1517 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
1522 /// use std::os::unix::net::UnixDatagram;
1523 /// use std::time::Duration;
1525 /// fn main() -> std::io::Result<()> {
1526 /// let socket = UnixDatagram::unbound()?;
1527 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
1528 /// let err = result.unwrap_err();
1529 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
1533 #[stable(feature = "unix_socket", since = "1.10.0")]
1534 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
1535 self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
1538 /// Returns the read timeout of this socket.
1543 /// use std::os::unix::net::UnixDatagram;
1544 /// use std::time::Duration;
1546 /// fn main() -> std::io::Result<()> {
1547 /// let sock = UnixDatagram::unbound()?;
1548 /// sock.set_read_timeout(Some(Duration::new(1, 0)))
1549 /// .expect("set_read_timeout function failed");
1550 /// assert_eq!(sock.read_timeout()?, Some(Duration::new(1, 0)));
1554 #[stable(feature = "unix_socket", since = "1.10.0")]
1555 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
1556 self.0.timeout(libc::SO_RCVTIMEO)
1559 /// Returns the write timeout of this socket.
1564 /// use std::os::unix::net::UnixDatagram;
1565 /// use std::time::Duration;
1567 /// fn main() -> std::io::Result<()> {
1568 /// let sock = UnixDatagram::unbound()?;
1569 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
1570 /// .expect("set_write_timeout function failed");
1571 /// assert_eq!(sock.write_timeout()?, Some(Duration::new(1, 0)));
1575 #[stable(feature = "unix_socket", since = "1.10.0")]
1576 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
1577 self.0.timeout(libc::SO_SNDTIMEO)
1580 /// Moves the socket into or out of nonblocking mode.
1585 /// use std::os::unix::net::UnixDatagram;
1587 /// fn main() -> std::io::Result<()> {
1588 /// let sock = UnixDatagram::unbound()?;
1589 /// sock.set_nonblocking(true).expect("set_nonblocking function failed");
1593 #[stable(feature = "unix_socket", since = "1.10.0")]
1594 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
1595 self.0.set_nonblocking(nonblocking)
1598 /// Returns the value of the `SO_ERROR` option.
1603 /// use std::os::unix::net::UnixDatagram;
1605 /// fn main() -> std::io::Result<()> {
1606 /// let sock = UnixDatagram::unbound()?;
1607 /// if let Ok(Some(err)) = sock.take_error() {
1608 /// println!("Got error: {:?}", err);
1613 #[stable(feature = "unix_socket", since = "1.10.0")]
1614 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
1618 /// Shut down the read, write, or both halves of this connection.
1620 /// This function will cause all pending and future I/O calls on the
1621 /// specified portions to immediately return with an appropriate value
1622 /// (see the documentation of [`Shutdown`]).
1625 /// use std::os::unix::net::UnixDatagram;
1626 /// use std::net::Shutdown;
1628 /// fn main() -> std::io::Result<()> {
1629 /// let sock = UnixDatagram::unbound()?;
1630 /// sock.shutdown(Shutdown::Both).expect("shutdown function failed");
1634 #[stable(feature = "unix_socket", since = "1.10.0")]
1635 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
1636 self.0.shutdown(how)
1639 /// Receives data on the socket from the remote address to which it is
1640 /// connected, without removing that data from the queue. On success,
1641 /// returns the number of bytes peeked.
1643 /// Successive calls return the same data. This is accomplished by passing
1644 /// `MSG_PEEK` as a flag to the underlying `recv` system call.
1649 /// #![feature(unix_socket_peek)]
1651 /// use std::os::unix::net::UnixDatagram;
1653 /// fn main() -> std::io::Result<()> {
1654 /// let socket = UnixDatagram::bind("/tmp/sock")?;
1655 /// let mut buf = [0; 10];
1656 /// let len = socket.peek(&mut buf).expect("peek failed");
1660 #[unstable(feature = "unix_socket_peek", issue = "none")]
1661 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
1665 /// Receives a single datagram message on the socket, without removing it from the
1666 /// queue. On success, returns the number of bytes read and the origin.
1668 /// The function must be called with valid byte array `buf` of sufficient size to
1669 /// hold the message bytes. If a message is too long to fit in the supplied buffer,
1670 /// excess bytes may be discarded.
1672 /// Successive calls return the same data. This is accomplished by passing
1673 /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call.
1675 /// Do not use this function to implement busy waiting, instead use `libc::poll` to
1676 /// synchronize IO events on one or more sockets.
1681 /// #![feature(unix_socket_peek)]
1683 /// use std::os::unix::net::UnixDatagram;
1685 /// fn main() -> std::io::Result<()> {
1686 /// let socket = UnixDatagram::bind("/tmp/sock")?;
1687 /// let mut buf = [0; 10];
1688 /// let (len, addr) = socket.peek_from(&mut buf).expect("peek failed");
1692 #[unstable(feature = "unix_socket_peek", issue = "none")]
1693 pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
1694 self.recv_from_flags(buf, libc::MSG_PEEK)
1698 #[stable(feature = "unix_socket", since = "1.10.0")]
1699 impl AsRawFd for UnixDatagram {
1700 fn as_raw_fd(&self) -> RawFd {
1705 #[stable(feature = "unix_socket", since = "1.10.0")]
1706 impl FromRawFd for UnixDatagram {
1707 unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
1708 UnixDatagram(Socket::from_inner(fd))
1712 #[stable(feature = "unix_socket", since = "1.10.0")]
1713 impl IntoRawFd for UnixDatagram {
1714 fn into_raw_fd(self) -> RawFd {