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;
34 target_os = "android",
36 target_os = "dragonfly",
37 target_os = "freebsd",
42 use crate::os::unix::ucred;
44 #[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")]
46 target_os = "android",
48 target_os = "dragonfly",
49 target_os = "freebsd",
58 target_os = "android",
59 target_os = "dragonfly",
60 target_os = "freebsd",
61 target_os = "openbsd",
65 use libc::MSG_NOSIGNAL;
68 target_os = "android",
69 target_os = "dragonfly",
70 target_os = "freebsd",
71 target_os = "openbsd",
75 const MSG_NOSIGNAL: libc::c_int = 0x0;
77 fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
78 // Work with an actual instance of the type since using a null pointer is UB
79 let base = addr as *const _ as usize;
80 let path = &addr.sun_path as *const _ as usize;
84 unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::socklen_t)> {
85 let mut addr: libc::sockaddr_un = mem::zeroed();
86 addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
88 let bytes = path.as_os_str().as_bytes();
90 if bytes.contains(&0) {
91 return Err(io::Error::new(
92 io::ErrorKind::InvalidInput,
93 "paths may not contain interior null bytes",
97 if bytes.len() >= addr.sun_path.len() {
98 return Err(io::Error::new(
99 io::ErrorKind::InvalidInput,
100 "path must be shorter than SUN_LEN",
103 for (dst, src) in addr.sun_path.iter_mut().zip(bytes.iter()) {
104 *dst = *src as libc::c_char;
106 // null byte for pathname addresses is already there because we zeroed the
109 let mut len = sun_path_offset(&addr) + bytes.len();
111 Some(&0) | None => {}
114 Ok((addr, len as libc::socklen_t))
117 enum AddressKind<'a> {
123 /// An address associated with a Unix socket.
128 /// use std::os::unix::net::UnixListener;
130 /// let socket = match UnixListener::bind("/tmp/sock") {
131 /// Ok(sock) => sock,
133 /// println!("Couldn't bind: {:?}", e);
137 /// let addr = socket.local_addr().expect("Couldn't get local address");
140 #[stable(feature = "unix_socket", since = "1.10.0")]
141 pub struct SocketAddr {
142 addr: libc::sockaddr_un,
143 len: libc::socklen_t,
147 fn new<F>(f: F) -> io::Result<SocketAddr>
149 F: FnOnce(*mut libc::sockaddr, *mut libc::socklen_t) -> libc::c_int,
152 let mut addr: libc::sockaddr_un = mem::zeroed();
153 let mut len = mem::size_of::<libc::sockaddr_un>() as libc::socklen_t;
154 cvt(f(&mut addr as *mut _ as *mut _, &mut len))?;
155 SocketAddr::from_parts(addr, len)
159 fn from_parts(addr: libc::sockaddr_un, mut len: libc::socklen_t) -> io::Result<SocketAddr> {
161 // When there is a datagram from unnamed unix socket
162 // linux returns zero bytes of address
163 len = sun_path_offset(&addr) as libc::socklen_t; // i.e., zero-length address
164 } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
165 return Err(io::Error::new(
166 io::ErrorKind::InvalidInput,
167 "file descriptor did not correspond to a Unix socket",
171 Ok(SocketAddr { addr, len })
174 /// Returns `true` if the address is unnamed.
181 /// use std::os::unix::net::UnixListener;
183 /// fn main() -> std::io::Result<()> {
184 /// let socket = UnixListener::bind("/tmp/sock")?;
185 /// let addr = socket.local_addr().expect("Couldn't get local address");
186 /// assert_eq!(addr.is_unnamed(), false);
191 /// An unnamed address:
194 /// use std::os::unix::net::UnixDatagram;
196 /// fn main() -> std::io::Result<()> {
197 /// let socket = UnixDatagram::unbound()?;
198 /// let addr = socket.local_addr().expect("Couldn't get local address");
199 /// assert_eq!(addr.is_unnamed(), true);
203 #[stable(feature = "unix_socket", since = "1.10.0")]
204 pub fn is_unnamed(&self) -> bool {
205 if let AddressKind::Unnamed = self.address() { true } else { false }
208 /// Returns the contents of this address if it is a `pathname` address.
215 /// use std::os::unix::net::UnixListener;
216 /// use std::path::Path;
218 /// fn main() -> std::io::Result<()> {
219 /// let socket = UnixListener::bind("/tmp/sock")?;
220 /// let addr = socket.local_addr().expect("Couldn't get local address");
221 /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock")));
226 /// Without a pathname:
229 /// use std::os::unix::net::UnixDatagram;
231 /// fn main() -> std::io::Result<()> {
232 /// let socket = UnixDatagram::unbound()?;
233 /// let addr = socket.local_addr().expect("Couldn't get local address");
234 /// assert_eq!(addr.as_pathname(), None);
238 #[stable(feature = "unix_socket", since = "1.10.0")]
239 pub fn as_pathname(&self) -> Option<&Path> {
240 if let AddressKind::Pathname(path) = self.address() { Some(path) } else { None }
243 fn address(&self) -> AddressKind<'_> {
244 let len = self.len as usize - sun_path_offset(&self.addr);
245 let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
247 // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
249 || (cfg!(not(any(target_os = "linux", target_os = "android")))
250 && self.addr.sun_path[0] == 0)
253 } else if self.addr.sun_path[0] == 0 {
254 AddressKind::Abstract(&path[1..len])
256 AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref())
261 #[stable(feature = "unix_socket", since = "1.10.0")]
262 impl fmt::Debug for SocketAddr {
263 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
264 match self.address() {
265 AddressKind::Unnamed => write!(fmt, "(unnamed)"),
266 AddressKind::Abstract(name) => write!(fmt, "{} (abstract)", AsciiEscaped(name)),
267 AddressKind::Pathname(path) => write!(fmt, "{:?} (pathname)", path),
272 struct AsciiEscaped<'a>(&'a [u8]);
274 impl<'a> fmt::Display for AsciiEscaped<'a> {
275 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
277 for byte in self.0.iter().cloned().flat_map(ascii::escape_default) {
278 write!(fmt, "{}", byte as char)?;
284 /// A Unix stream socket.
289 /// use std::os::unix::net::UnixStream;
290 /// use std::io::prelude::*;
292 /// fn main() -> std::io::Result<()> {
293 /// let mut stream = UnixStream::connect("/path/to/my/socket")?;
294 /// stream.write_all(b"hello world")?;
295 /// let mut response = String::new();
296 /// stream.read_to_string(&mut response)?;
297 /// println!("{}", response);
301 #[stable(feature = "unix_socket", since = "1.10.0")]
302 pub struct UnixStream(Socket);
304 #[stable(feature = "unix_socket", since = "1.10.0")]
305 impl fmt::Debug for UnixStream {
306 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
307 let mut builder = fmt.debug_struct("UnixStream");
308 builder.field("fd", self.0.as_inner());
309 if let Ok(addr) = self.local_addr() {
310 builder.field("local", &addr);
312 if let Ok(addr) = self.peer_addr() {
313 builder.field("peer", &addr);
320 /// Connects to the socket named by `path`.
325 /// use std::os::unix::net::UnixStream;
327 /// let socket = match UnixStream::connect("/tmp/sock") {
328 /// Ok(sock) => sock,
330 /// println!("Couldn't connect: {:?}", e);
335 #[stable(feature = "unix_socket", since = "1.10.0")]
336 pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
337 fn inner(path: &Path) -> io::Result<UnixStream> {
339 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
340 let (addr, len) = sockaddr_un(path)?;
342 cvt(libc::connect(*inner.as_inner(), &addr as *const _ as *const _, len))?;
343 Ok(UnixStream(inner))
349 /// Creates an unnamed pair of connected sockets.
351 /// Returns two `UnixStream`s which are connected to each other.
356 /// use std::os::unix::net::UnixStream;
358 /// let (sock1, sock2) = match UnixStream::pair() {
359 /// Ok((sock1, sock2)) => (sock1, sock2),
361 /// println!("Couldn't create a pair of sockets: {:?}", e);
366 #[stable(feature = "unix_socket", since = "1.10.0")]
367 pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
368 let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
369 Ok((UnixStream(i1), UnixStream(i2)))
372 /// Creates a new independently owned handle to the underlying socket.
374 /// The returned `UnixStream` is a reference to the same stream that this
375 /// object references. Both handles will read and write the same stream of
376 /// data, and options set on one stream will be propagated to the other
382 /// use std::os::unix::net::UnixStream;
384 /// fn main() -> std::io::Result<()> {
385 /// let socket = UnixStream::connect("/tmp/sock")?;
386 /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
390 #[stable(feature = "unix_socket", since = "1.10.0")]
391 pub fn try_clone(&self) -> io::Result<UnixStream> {
392 self.0.duplicate().map(UnixStream)
395 /// Returns the socket address of the local half of this connection.
400 /// use std::os::unix::net::UnixStream;
402 /// fn main() -> std::io::Result<()> {
403 /// let socket = UnixStream::connect("/tmp/sock")?;
404 /// let addr = socket.local_addr().expect("Couldn't get local address");
408 #[stable(feature = "unix_socket", since = "1.10.0")]
409 pub fn local_addr(&self) -> io::Result<SocketAddr> {
410 SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
413 /// Returns the socket address of the remote half of this connection.
418 /// use std::os::unix::net::UnixStream;
420 /// fn main() -> std::io::Result<()> {
421 /// let socket = UnixStream::connect("/tmp/sock")?;
422 /// let addr = socket.peer_addr().expect("Couldn't get peer address");
426 #[stable(feature = "unix_socket", since = "1.10.0")]
427 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
428 SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
431 /// Gets the peer credentials for this Unix domain socket.
436 /// #![feature(peer_credentials_unix_socket)]
437 /// use std::os::unix::net::UnixStream;
439 /// fn main() -> std::io::Result<()> {
440 /// let socket = UnixStream::connect("/tmp/sock")?;
441 /// let peer_cred = socket.peer_cred().expect("Couldn't get peer credentials");
445 #[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")]
447 target_os = "android",
449 target_os = "dragonfly",
450 target_os = "freebsd",
453 target_os = "openbsd"
455 pub fn peer_cred(&self) -> io::Result<UCred> {
456 ucred::peer_cred(self)
459 /// Sets the read timeout for the socket.
461 /// If the provided value is [`None`], then [`read`] calls will block
462 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
465 /// [`read`]: io::Read::read
470 /// use std::os::unix::net::UnixStream;
471 /// use std::time::Duration;
473 /// fn main() -> std::io::Result<()> {
474 /// let socket = UnixStream::connect("/tmp/sock")?;
475 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
480 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
485 /// use std::os::unix::net::UnixStream;
486 /// use std::time::Duration;
488 /// fn main() -> std::io::Result<()> {
489 /// let socket = UnixStream::connect("/tmp/sock")?;
490 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
491 /// let err = result.unwrap_err();
492 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
496 #[stable(feature = "unix_socket", since = "1.10.0")]
497 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
498 self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
501 /// Sets the write timeout for the socket.
503 /// If the provided value is [`None`], then [`write`] calls will block
504 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
505 /// passed to this method.
507 /// [`read`]: io::Read::read
512 /// use std::os::unix::net::UnixStream;
513 /// use std::time::Duration;
515 /// fn main() -> std::io::Result<()> {
516 /// let socket = UnixStream::connect("/tmp/sock")?;
517 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
518 /// .expect("Couldn't set write timeout");
523 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
528 /// use std::net::UdpSocket;
529 /// use std::time::Duration;
531 /// fn main() -> std::io::Result<()> {
532 /// let socket = UdpSocket::bind("127.0.0.1:34254")?;
533 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
534 /// let err = result.unwrap_err();
535 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
539 #[stable(feature = "unix_socket", since = "1.10.0")]
540 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
541 self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
544 /// Returns the read timeout of this socket.
549 /// use std::os::unix::net::UnixStream;
550 /// use std::time::Duration;
552 /// fn main() -> std::io::Result<()> {
553 /// let socket = UnixStream::connect("/tmp/sock")?;
554 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
555 /// assert_eq!(socket.read_timeout()?, Some(Duration::new(1, 0)));
559 #[stable(feature = "unix_socket", since = "1.10.0")]
560 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
561 self.0.timeout(libc::SO_RCVTIMEO)
564 /// Returns the write timeout of this socket.
569 /// use std::os::unix::net::UnixStream;
570 /// use std::time::Duration;
572 /// fn main() -> std::io::Result<()> {
573 /// let socket = UnixStream::connect("/tmp/sock")?;
574 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
575 /// .expect("Couldn't set write timeout");
576 /// assert_eq!(socket.write_timeout()?, Some(Duration::new(1, 0)));
580 #[stable(feature = "unix_socket", since = "1.10.0")]
581 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
582 self.0.timeout(libc::SO_SNDTIMEO)
585 /// Moves the socket into or out of nonblocking mode.
590 /// use std::os::unix::net::UnixStream;
592 /// fn main() -> std::io::Result<()> {
593 /// let socket = UnixStream::connect("/tmp/sock")?;
594 /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
598 #[stable(feature = "unix_socket", since = "1.10.0")]
599 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
600 self.0.set_nonblocking(nonblocking)
603 /// Returns the value of the `SO_ERROR` option.
608 /// use std::os::unix::net::UnixStream;
610 /// fn main() -> std::io::Result<()> {
611 /// let socket = UnixStream::connect("/tmp/sock")?;
612 /// if let Ok(Some(err)) = socket.take_error() {
613 /// println!("Got error: {:?}", err);
619 /// # Platform specific
620 /// On Redox this always returns `None`.
621 #[stable(feature = "unix_socket", since = "1.10.0")]
622 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
626 /// Shuts down the read, write, or both halves of this connection.
628 /// This function will cause all pending and future I/O calls on the
629 /// specified portions to immediately return with an appropriate value
630 /// (see the documentation of [`Shutdown`]).
635 /// use std::os::unix::net::UnixStream;
636 /// use std::net::Shutdown;
638 /// fn main() -> std::io::Result<()> {
639 /// let socket = UnixStream::connect("/tmp/sock")?;
640 /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
644 #[stable(feature = "unix_socket", since = "1.10.0")]
645 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
649 /// Receives data on the socket from the remote address to which it is
650 /// connected, without removing that data from the queue. On success,
651 /// returns the number of bytes peeked.
653 /// Successive calls return the same data. This is accomplished by passing
654 /// `MSG_PEEK` as a flag to the underlying `recv` system call.
659 /// #![feature(unix_socket_peek)]
661 /// use std::os::unix::net::UnixStream;
663 /// fn main() -> std::io::Result<()> {
664 /// let socket = UnixStream::connect("/tmp/sock")?;
665 /// let mut buf = [0; 10];
666 /// let len = socket.peek(&mut buf).expect("peek failed");
670 #[unstable(feature = "unix_socket_peek", issue = "76923")]
671 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
676 #[stable(feature = "unix_socket", since = "1.10.0")]
677 impl io::Read for UnixStream {
678 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
679 io::Read::read(&mut &*self, buf)
682 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
683 io::Read::read_vectored(&mut &*self, bufs)
687 fn is_read_vectored(&self) -> bool {
688 io::Read::is_read_vectored(&&*self)
692 unsafe fn initializer(&self) -> Initializer {
697 #[stable(feature = "unix_socket", since = "1.10.0")]
698 impl<'a> io::Read for &'a UnixStream {
699 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
703 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
704 self.0.read_vectored(bufs)
708 fn is_read_vectored(&self) -> bool {
709 self.0.is_read_vectored()
713 unsafe fn initializer(&self) -> Initializer {
718 #[stable(feature = "unix_socket", since = "1.10.0")]
719 impl io::Write for UnixStream {
720 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
721 io::Write::write(&mut &*self, buf)
724 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
725 io::Write::write_vectored(&mut &*self, bufs)
729 fn is_write_vectored(&self) -> bool {
730 io::Write::is_write_vectored(&&*self)
733 fn flush(&mut self) -> io::Result<()> {
734 io::Write::flush(&mut &*self)
738 #[stable(feature = "unix_socket", since = "1.10.0")]
739 impl<'a> io::Write for &'a UnixStream {
740 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
744 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
745 self.0.write_vectored(bufs)
749 fn is_write_vectored(&self) -> bool {
750 self.0.is_write_vectored()
753 fn flush(&mut self) -> io::Result<()> {
758 #[stable(feature = "unix_socket", since = "1.10.0")]
759 impl AsRawFd for UnixStream {
760 fn as_raw_fd(&self) -> RawFd {
765 #[stable(feature = "unix_socket", since = "1.10.0")]
766 impl FromRawFd for UnixStream {
767 unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
768 UnixStream(Socket::from_inner(fd))
772 #[stable(feature = "unix_socket", since = "1.10.0")]
773 impl IntoRawFd for UnixStream {
774 fn into_raw_fd(self) -> RawFd {
779 #[stable(feature = "rust1", since = "1.0.0")]
780 impl AsRawFd for net::TcpStream {
781 fn as_raw_fd(&self) -> RawFd {
782 *self.as_inner().socket().as_inner()
786 #[stable(feature = "rust1", since = "1.0.0")]
787 impl AsRawFd for net::TcpListener {
788 fn as_raw_fd(&self) -> RawFd {
789 *self.as_inner().socket().as_inner()
793 #[stable(feature = "rust1", since = "1.0.0")]
794 impl AsRawFd for net::UdpSocket {
795 fn as_raw_fd(&self) -> RawFd {
796 *self.as_inner().socket().as_inner()
800 #[stable(feature = "from_raw_os", since = "1.1.0")]
801 impl FromRawFd for net::TcpStream {
802 unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
803 let socket = sys::net::Socket::from_inner(fd);
804 net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(socket))
808 #[stable(feature = "from_raw_os", since = "1.1.0")]
809 impl FromRawFd for net::TcpListener {
810 unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
811 let socket = sys::net::Socket::from_inner(fd);
812 net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(socket))
816 #[stable(feature = "from_raw_os", since = "1.1.0")]
817 impl FromRawFd for net::UdpSocket {
818 unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
819 let socket = sys::net::Socket::from_inner(fd);
820 net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(socket))
824 #[stable(feature = "into_raw_os", since = "1.4.0")]
825 impl IntoRawFd for net::TcpStream {
826 fn into_raw_fd(self) -> RawFd {
827 self.into_inner().into_socket().into_inner()
830 #[stable(feature = "into_raw_os", since = "1.4.0")]
831 impl IntoRawFd for net::TcpListener {
832 fn into_raw_fd(self) -> RawFd {
833 self.into_inner().into_socket().into_inner()
836 #[stable(feature = "into_raw_os", since = "1.4.0")]
837 impl IntoRawFd for net::UdpSocket {
838 fn into_raw_fd(self) -> RawFd {
839 self.into_inner().into_socket().into_inner()
843 /// A structure representing a Unix domain socket server.
849 /// use std::os::unix::net::{UnixStream, UnixListener};
851 /// fn handle_client(stream: UnixStream) {
855 /// fn main() -> std::io::Result<()> {
856 /// let listener = UnixListener::bind("/path/to/the/socket")?;
858 /// // accept connections and process them, spawning a new thread for each one
859 /// for stream in listener.incoming() {
862 /// /* connection succeeded */
863 /// thread::spawn(|| handle_client(stream));
866 /// /* connection failed */
874 #[stable(feature = "unix_socket", since = "1.10.0")]
875 pub struct UnixListener(Socket);
877 #[stable(feature = "unix_socket", since = "1.10.0")]
878 impl fmt::Debug for UnixListener {
879 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
880 let mut builder = fmt.debug_struct("UnixListener");
881 builder.field("fd", self.0.as_inner());
882 if let Ok(addr) = self.local_addr() {
883 builder.field("local", &addr);
890 /// Creates a new `UnixListener` bound to the specified socket.
895 /// use std::os::unix::net::UnixListener;
897 /// let listener = match UnixListener::bind("/path/to/the/socket") {
898 /// Ok(sock) => sock,
900 /// println!("Couldn't connect: {:?}", e);
905 #[stable(feature = "unix_socket", since = "1.10.0")]
906 pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
907 fn inner(path: &Path) -> io::Result<UnixListener> {
909 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
910 let (addr, len) = sockaddr_un(path)?;
912 cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len as _))?;
913 cvt(libc::listen(*inner.as_inner(), 128))?;
915 Ok(UnixListener(inner))
921 /// Accepts a new incoming connection to this listener.
923 /// This function will block the calling thread until a new Unix connection
924 /// is established. When established, the corresponding [`UnixStream`] and
925 /// the remote peer's address will be returned.
927 /// [`UnixStream`]: crate::os::unix::net::UnixStream
932 /// use std::os::unix::net::UnixListener;
934 /// fn main() -> std::io::Result<()> {
935 /// let listener = UnixListener::bind("/path/to/the/socket")?;
937 /// match listener.accept() {
938 /// Ok((socket, addr)) => println!("Got a client: {:?}", addr),
939 /// Err(e) => println!("accept function failed: {:?}", e),
944 #[stable(feature = "unix_socket", since = "1.10.0")]
945 pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
946 let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() };
947 let mut len = mem::size_of_val(&storage) as libc::socklen_t;
948 let sock = self.0.accept(&mut storage as *mut _ as *mut _, &mut len)?;
949 let addr = SocketAddr::from_parts(storage, len)?;
950 Ok((UnixStream(sock), addr))
953 /// Creates a new independently owned handle to the underlying socket.
955 /// The returned `UnixListener` is a reference to the same socket that this
956 /// object references. Both handles can be used to accept incoming
957 /// connections and options set on one listener will affect the other.
962 /// use std::os::unix::net::UnixListener;
964 /// fn main() -> std::io::Result<()> {
965 /// let listener = UnixListener::bind("/path/to/the/socket")?;
966 /// let listener_copy = listener.try_clone().expect("try_clone failed");
970 #[stable(feature = "unix_socket", since = "1.10.0")]
971 pub fn try_clone(&self) -> io::Result<UnixListener> {
972 self.0.duplicate().map(UnixListener)
975 /// Returns the local socket address of this listener.
980 /// use std::os::unix::net::UnixListener;
982 /// fn main() -> std::io::Result<()> {
983 /// let listener = UnixListener::bind("/path/to/the/socket")?;
984 /// let addr = listener.local_addr().expect("Couldn't get local address");
988 #[stable(feature = "unix_socket", since = "1.10.0")]
989 pub fn local_addr(&self) -> io::Result<SocketAddr> {
990 SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
993 /// Moves the socket into or out of nonblocking mode.
995 /// This will result in the `accept` operation becoming nonblocking,
996 /// i.e., immediately returning from their calls. If the IO operation is
997 /// successful, `Ok` is returned and no further action is required. If the
998 /// IO operation could not be completed and needs to be retried, an error
999 /// with kind [`io::ErrorKind::WouldBlock`] is returned.
1004 /// use std::os::unix::net::UnixListener;
1006 /// fn main() -> std::io::Result<()> {
1007 /// let listener = UnixListener::bind("/path/to/the/socket")?;
1008 /// listener.set_nonblocking(true).expect("Couldn't set non blocking");
1012 #[stable(feature = "unix_socket", since = "1.10.0")]
1013 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
1014 self.0.set_nonblocking(nonblocking)
1017 /// Returns the value of the `SO_ERROR` option.
1022 /// use std::os::unix::net::UnixListener;
1024 /// fn main() -> std::io::Result<()> {
1025 /// let listener = UnixListener::bind("/tmp/sock")?;
1027 /// if let Ok(Some(err)) = listener.take_error() {
1028 /// println!("Got error: {:?}", err);
1034 /// # Platform specific
1035 /// On Redox this always returns `None`.
1036 #[stable(feature = "unix_socket", since = "1.10.0")]
1037 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
1041 /// Returns an iterator over incoming connections.
1043 /// The iterator will never return [`None`] and will also not yield the
1044 /// peer's [`SocketAddr`] structure.
1049 /// use std::thread;
1050 /// use std::os::unix::net::{UnixStream, UnixListener};
1052 /// fn handle_client(stream: UnixStream) {
1056 /// fn main() -> std::io::Result<()> {
1057 /// let listener = UnixListener::bind("/path/to/the/socket")?;
1059 /// for stream in listener.incoming() {
1062 /// thread::spawn(|| handle_client(stream));
1072 #[stable(feature = "unix_socket", since = "1.10.0")]
1073 pub fn incoming(&self) -> Incoming<'_> {
1074 Incoming { listener: self }
1078 #[stable(feature = "unix_socket", since = "1.10.0")]
1079 impl AsRawFd for UnixListener {
1080 fn as_raw_fd(&self) -> RawFd {
1085 #[stable(feature = "unix_socket", since = "1.10.0")]
1086 impl FromRawFd for UnixListener {
1087 unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
1088 UnixListener(Socket::from_inner(fd))
1092 #[stable(feature = "unix_socket", since = "1.10.0")]
1093 impl IntoRawFd for UnixListener {
1094 fn into_raw_fd(self) -> RawFd {
1099 #[stable(feature = "unix_socket", since = "1.10.0")]
1100 impl<'a> IntoIterator for &'a UnixListener {
1101 type Item = io::Result<UnixStream>;
1102 type IntoIter = Incoming<'a>;
1104 fn into_iter(self) -> Incoming<'a> {
1109 /// An iterator over incoming connections to a [`UnixListener`].
1111 /// It will never return [`None`].
1116 /// use std::thread;
1117 /// use std::os::unix::net::{UnixStream, UnixListener};
1119 /// fn handle_client(stream: UnixStream) {
1123 /// fn main() -> std::io::Result<()> {
1124 /// let listener = UnixListener::bind("/path/to/the/socket")?;
1126 /// for stream in listener.incoming() {
1129 /// thread::spawn(|| handle_client(stream));
1140 #[stable(feature = "unix_socket", since = "1.10.0")]
1141 pub struct Incoming<'a> {
1142 listener: &'a UnixListener,
1145 #[stable(feature = "unix_socket", since = "1.10.0")]
1146 impl<'a> Iterator for Incoming<'a> {
1147 type Item = io::Result<UnixStream>;
1149 fn next(&mut self) -> Option<io::Result<UnixStream>> {
1150 Some(self.listener.accept().map(|s| s.0))
1153 fn size_hint(&self) -> (usize, Option<usize>) {
1158 /// A Unix datagram socket.
1163 /// use std::os::unix::net::UnixDatagram;
1165 /// fn main() -> std::io::Result<()> {
1166 /// let socket = UnixDatagram::bind("/path/to/my/socket")?;
1167 /// socket.send_to(b"hello world", "/path/to/other/socket")?;
1168 /// let mut buf = [0; 100];
1169 /// let (count, address) = socket.recv_from(&mut buf)?;
1170 /// println!("socket {:?} sent {:?}", address, &buf[..count]);
1174 #[stable(feature = "unix_socket", since = "1.10.0")]
1175 pub struct UnixDatagram(Socket);
1177 #[stable(feature = "unix_socket", since = "1.10.0")]
1178 impl fmt::Debug for UnixDatagram {
1179 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1180 let mut builder = fmt.debug_struct("UnixDatagram");
1181 builder.field("fd", self.0.as_inner());
1182 if let Ok(addr) = self.local_addr() {
1183 builder.field("local", &addr);
1185 if let Ok(addr) = self.peer_addr() {
1186 builder.field("peer", &addr);
1193 /// Creates a Unix datagram socket bound to the given path.
1198 /// use std::os::unix::net::UnixDatagram;
1200 /// let sock = match UnixDatagram::bind("/path/to/the/socket") {
1201 /// Ok(sock) => sock,
1203 /// println!("Couldn't bind: {:?}", e);
1208 #[stable(feature = "unix_socket", since = "1.10.0")]
1209 pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
1210 fn inner(path: &Path) -> io::Result<UnixDatagram> {
1212 let socket = UnixDatagram::unbound()?;
1213 let (addr, len) = sockaddr_un(path)?;
1215 cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len as _))?;
1220 inner(path.as_ref())
1223 /// Creates a Unix Datagram socket which is not bound to any address.
1228 /// use std::os::unix::net::UnixDatagram;
1230 /// let sock = match UnixDatagram::unbound() {
1231 /// Ok(sock) => sock,
1233 /// println!("Couldn't unbound: {:?}", e);
1238 #[stable(feature = "unix_socket", since = "1.10.0")]
1239 pub fn unbound() -> io::Result<UnixDatagram> {
1240 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?;
1241 Ok(UnixDatagram(inner))
1244 /// Creates an unnamed pair of connected sockets.
1246 /// Returns two `UnixDatagrams`s which are connected to each other.
1251 /// use std::os::unix::net::UnixDatagram;
1253 /// let (sock1, sock2) = match UnixDatagram::pair() {
1254 /// Ok((sock1, sock2)) => (sock1, sock2),
1256 /// println!("Couldn't unbound: {:?}", e);
1261 #[stable(feature = "unix_socket", since = "1.10.0")]
1262 pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
1263 let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?;
1264 Ok((UnixDatagram(i1), UnixDatagram(i2)))
1267 /// Connects the socket to the specified address.
1269 /// The [`send`] method may be used to send data to the specified address.
1270 /// [`recv`] and [`recv_from`] will only receive data from that address.
1272 /// [`send`]: UnixDatagram::send
1273 /// [`recv`]: UnixDatagram::recv
1274 /// [`recv_from`]: UnixDatagram::recv_from
1279 /// use std::os::unix::net::UnixDatagram;
1281 /// fn main() -> std::io::Result<()> {
1282 /// let sock = UnixDatagram::unbound()?;
1283 /// match sock.connect("/path/to/the/socket") {
1284 /// Ok(sock) => sock,
1286 /// println!("Couldn't connect: {:?}", e);
1293 #[stable(feature = "unix_socket", since = "1.10.0")]
1294 pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
1295 fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> {
1297 let (addr, len) = sockaddr_un(path)?;
1299 cvt(libc::connect(*d.0.as_inner(), &addr as *const _ as *const _, len))?;
1304 inner(self, path.as_ref())
1307 /// Creates a new independently owned handle to the underlying socket.
1309 /// The returned `UnixDatagram` is a reference to the same socket that this
1310 /// object references. Both handles can be used to accept incoming
1311 /// connections and options set on one side will affect the other.
1316 /// use std::os::unix::net::UnixDatagram;
1318 /// fn main() -> std::io::Result<()> {
1319 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
1320 /// let sock_copy = sock.try_clone().expect("try_clone failed");
1324 #[stable(feature = "unix_socket", since = "1.10.0")]
1325 pub fn try_clone(&self) -> io::Result<UnixDatagram> {
1326 self.0.duplicate().map(UnixDatagram)
1329 /// Returns the address of this socket.
1334 /// use std::os::unix::net::UnixDatagram;
1336 /// fn main() -> std::io::Result<()> {
1337 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
1338 /// let addr = sock.local_addr().expect("Couldn't get local address");
1342 #[stable(feature = "unix_socket", since = "1.10.0")]
1343 pub fn local_addr(&self) -> io::Result<SocketAddr> {
1344 SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
1347 /// Returns the address of this socket's peer.
1349 /// The [`connect`] method will connect the socket to a peer.
1351 /// [`connect`]: UnixDatagram::connect
1356 /// use std::os::unix::net::UnixDatagram;
1358 /// fn main() -> std::io::Result<()> {
1359 /// let sock = UnixDatagram::unbound()?;
1360 /// sock.connect("/path/to/the/socket")?;
1362 /// let addr = sock.peer_addr().expect("Couldn't get peer address");
1366 #[stable(feature = "unix_socket", since = "1.10.0")]
1367 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
1368 SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
1375 ) -> io::Result<(usize, SocketAddr)> {
1377 let addr = SocketAddr::new(|addr, len| unsafe {
1378 count = libc::recvfrom(
1380 buf.as_mut_ptr() as *mut _,
1388 } else if count == 0 {
1395 Ok((count as usize, addr))
1398 /// Receives data from the socket.
1400 /// On success, returns the number of bytes read and the address from
1401 /// whence the data came.
1406 /// use std::os::unix::net::UnixDatagram;
1408 /// fn main() -> std::io::Result<()> {
1409 /// let sock = UnixDatagram::unbound()?;
1410 /// let mut buf = vec![0; 10];
1411 /// let (size, sender) = sock.recv_from(buf.as_mut_slice())?;
1412 /// println!("received {} bytes from {:?}", size, sender);
1416 #[stable(feature = "unix_socket", since = "1.10.0")]
1417 pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
1418 self.recv_from_flags(buf, 0)
1421 /// Receives data from the socket.
1423 /// On success, returns the number of bytes read.
1428 /// use std::os::unix::net::UnixDatagram;
1430 /// fn main() -> std::io::Result<()> {
1431 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
1432 /// let mut buf = vec![0; 10];
1433 /// sock.recv(buf.as_mut_slice()).expect("recv function failed");
1437 #[stable(feature = "unix_socket", since = "1.10.0")]
1438 pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
1442 /// Sends data on the socket to the specified address.
1444 /// On success, returns the number of bytes written.
1449 /// use std::os::unix::net::UnixDatagram;
1451 /// fn main() -> std::io::Result<()> {
1452 /// let sock = UnixDatagram::unbound()?;
1453 /// sock.send_to(b"omelette au fromage", "/some/sock").expect("send_to function failed");
1457 #[stable(feature = "unix_socket", since = "1.10.0")]
1458 pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
1459 fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result<usize> {
1461 let (addr, len) = sockaddr_un(path)?;
1463 let count = cvt(libc::sendto(
1465 buf.as_ptr() as *const _,
1468 &addr as *const _ as *const _,
1474 inner(self, buf, path.as_ref())
1477 /// Sends data on the socket to the socket's peer.
1479 /// The peer address may be set by the `connect` method, and this method
1480 /// will return an error if the socket has not already been connected.
1482 /// On success, returns the number of bytes written.
1487 /// use std::os::unix::net::UnixDatagram;
1489 /// fn main() -> std::io::Result<()> {
1490 /// let sock = UnixDatagram::unbound()?;
1491 /// sock.connect("/some/sock").expect("Couldn't connect");
1492 /// sock.send(b"omelette au fromage").expect("send_to function failed");
1496 #[stable(feature = "unix_socket", since = "1.10.0")]
1497 pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
1501 /// Sets the read timeout for the socket.
1503 /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will
1504 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`]
1505 /// is passed to this method.
1507 /// [`recv`]: UnixDatagram::recv
1508 /// [`recv_from`]: UnixDatagram::recv_from
1513 /// use std::os::unix::net::UnixDatagram;
1514 /// use std::time::Duration;
1516 /// fn main() -> std::io::Result<()> {
1517 /// let sock = UnixDatagram::unbound()?;
1518 /// sock.set_read_timeout(Some(Duration::new(1, 0)))
1519 /// .expect("set_read_timeout function failed");
1524 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
1529 /// use std::os::unix::net::UnixDatagram;
1530 /// use std::time::Duration;
1532 /// fn main() -> std::io::Result<()> {
1533 /// let socket = UnixDatagram::unbound()?;
1534 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
1535 /// let err = result.unwrap_err();
1536 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
1540 #[stable(feature = "unix_socket", since = "1.10.0")]
1541 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
1542 self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
1545 /// Sets the write timeout for the socket.
1547 /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will
1548 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
1551 /// [`send`]: UnixDatagram::send
1552 /// [`send_to`]: UnixDatagram::send_to
1557 /// use std::os::unix::net::UnixDatagram;
1558 /// use std::time::Duration;
1560 /// fn main() -> std::io::Result<()> {
1561 /// let sock = UnixDatagram::unbound()?;
1562 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
1563 /// .expect("set_write_timeout function failed");
1568 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
1573 /// use std::os::unix::net::UnixDatagram;
1574 /// use std::time::Duration;
1576 /// fn main() -> std::io::Result<()> {
1577 /// let socket = UnixDatagram::unbound()?;
1578 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
1579 /// let err = result.unwrap_err();
1580 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
1584 #[stable(feature = "unix_socket", since = "1.10.0")]
1585 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
1586 self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
1589 /// Returns the read timeout of this socket.
1594 /// use std::os::unix::net::UnixDatagram;
1595 /// use std::time::Duration;
1597 /// fn main() -> std::io::Result<()> {
1598 /// let sock = UnixDatagram::unbound()?;
1599 /// sock.set_read_timeout(Some(Duration::new(1, 0)))
1600 /// .expect("set_read_timeout function failed");
1601 /// assert_eq!(sock.read_timeout()?, Some(Duration::new(1, 0)));
1605 #[stable(feature = "unix_socket", since = "1.10.0")]
1606 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
1607 self.0.timeout(libc::SO_RCVTIMEO)
1610 /// Returns the write timeout of this socket.
1615 /// use std::os::unix::net::UnixDatagram;
1616 /// use std::time::Duration;
1618 /// fn main() -> std::io::Result<()> {
1619 /// let sock = UnixDatagram::unbound()?;
1620 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
1621 /// .expect("set_write_timeout function failed");
1622 /// assert_eq!(sock.write_timeout()?, Some(Duration::new(1, 0)));
1626 #[stable(feature = "unix_socket", since = "1.10.0")]
1627 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
1628 self.0.timeout(libc::SO_SNDTIMEO)
1631 /// Moves the socket into or out of nonblocking mode.
1636 /// use std::os::unix::net::UnixDatagram;
1638 /// fn main() -> std::io::Result<()> {
1639 /// let sock = UnixDatagram::unbound()?;
1640 /// sock.set_nonblocking(true).expect("set_nonblocking function failed");
1644 #[stable(feature = "unix_socket", since = "1.10.0")]
1645 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
1646 self.0.set_nonblocking(nonblocking)
1649 /// Returns the value of the `SO_ERROR` option.
1654 /// use std::os::unix::net::UnixDatagram;
1656 /// fn main() -> std::io::Result<()> {
1657 /// let sock = UnixDatagram::unbound()?;
1658 /// if let Ok(Some(err)) = sock.take_error() {
1659 /// println!("Got error: {:?}", err);
1664 #[stable(feature = "unix_socket", since = "1.10.0")]
1665 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
1669 /// Shut down the read, write, or both halves of this connection.
1671 /// This function will cause all pending and future I/O calls on the
1672 /// specified portions to immediately return with an appropriate value
1673 /// (see the documentation of [`Shutdown`]).
1676 /// use std::os::unix::net::UnixDatagram;
1677 /// use std::net::Shutdown;
1679 /// fn main() -> std::io::Result<()> {
1680 /// let sock = UnixDatagram::unbound()?;
1681 /// sock.shutdown(Shutdown::Both).expect("shutdown function failed");
1685 #[stable(feature = "unix_socket", since = "1.10.0")]
1686 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
1687 self.0.shutdown(how)
1690 /// Receives data on the socket from the remote address to which it is
1691 /// connected, without removing that data from the queue. On success,
1692 /// returns the number of bytes peeked.
1694 /// Successive calls return the same data. This is accomplished by passing
1695 /// `MSG_PEEK` as a flag to the underlying `recv` system call.
1700 /// #![feature(unix_socket_peek)]
1702 /// use std::os::unix::net::UnixDatagram;
1704 /// fn main() -> std::io::Result<()> {
1705 /// let socket = UnixDatagram::bind("/tmp/sock")?;
1706 /// let mut buf = [0; 10];
1707 /// let len = socket.peek(&mut buf).expect("peek failed");
1711 #[unstable(feature = "unix_socket_peek", issue = "76923")]
1712 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
1716 /// Receives a single datagram message on the socket, without removing it from the
1717 /// queue. On success, returns the number of bytes read and the origin.
1719 /// The function must be called with valid byte array `buf` of sufficient size to
1720 /// hold the message bytes. If a message is too long to fit in the supplied buffer,
1721 /// excess bytes may be discarded.
1723 /// Successive calls return the same data. This is accomplished by passing
1724 /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call.
1726 /// Do not use this function to implement busy waiting, instead use `libc::poll` to
1727 /// synchronize IO events on one or more sockets.
1732 /// #![feature(unix_socket_peek)]
1734 /// use std::os::unix::net::UnixDatagram;
1736 /// fn main() -> std::io::Result<()> {
1737 /// let socket = UnixDatagram::bind("/tmp/sock")?;
1738 /// let mut buf = [0; 10];
1739 /// let (len, addr) = socket.peek_from(&mut buf).expect("peek failed");
1743 #[unstable(feature = "unix_socket_peek", issue = "76923")]
1744 pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
1745 self.recv_from_flags(buf, libc::MSG_PEEK)
1749 #[stable(feature = "unix_socket", since = "1.10.0")]
1750 impl AsRawFd for UnixDatagram {
1751 fn as_raw_fd(&self) -> RawFd {
1756 #[stable(feature = "unix_socket", since = "1.10.0")]
1757 impl FromRawFd for UnixDatagram {
1758 unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
1759 UnixDatagram(Socket::from_inner(fd))
1763 #[stable(feature = "unix_socket", since = "1.10.0")]
1764 impl IntoRawFd for UnixDatagram {
1765 fn into_raw_fd(self) -> RawFd {