1 #![stable(feature = "unix_socket", since = "1.10.0")]
3 //! Unix-specific networking functionality
8 // FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here?
12 pub type socklen_t
= u32;
15 pub struct sockaddr_un
;
19 use crate::ffi
::OsStr
;
21 use crate::io
::{self, Initializer, IoSlice, IoSliceMut}
;
23 use crate::net
::{self, Shutdown}
;
24 use crate::os
::unix
::ffi
::OsStrExt
;
25 use crate::os
::unix
::io
::{RawFd, AsRawFd, FromRawFd, IntoRawFd}
;
26 use crate::path
::Path
;
27 use crate::time
::Duration
;
28 use crate::sys
::{self, cvt}
;
29 use crate::sys
::net
::Socket
;
30 use crate::sys_common
::{self, AsInner, FromInner, IntoInner}
;
32 #[cfg(any(target_os = "linux", target_os = "android",
33 target_os
= "dragonfly", target_os
= "freebsd",
34 target_os
= "openbsd", target_os
= "netbsd",
35 target_os
= "haiku"))]
36 use libc
::MSG_NOSIGNAL
;
37 #[cfg(not(any(target_os = "linux", target_os = "android",
38 target_os
= "dragonfly", target_os
= "freebsd",
39 target_os
= "openbsd", target_os
= "netbsd",
40 target_os
= "haiku")))]
41 const MSG_NOSIGNAL
: libc
::c_int
= 0x0;
43 fn sun_path_offset(addr
: &libc
::sockaddr_un
) -> usize {
44 // Work with an actual instance of the type since using a null pointer is UB
45 let base
= addr
as *const _
as usize;
46 let path
= &addr
.sun_path
as *const _
as usize;
50 unsafe fn sockaddr_un(path
: &Path
) -> io
::Result
<(libc
::sockaddr_un
, libc
::socklen_t
)> {
51 let mut addr
: libc
::sockaddr_un
= mem
::zeroed();
52 addr
.sun_family
= libc
::AF_UNIX
as libc
::sa_family_t
;
54 let bytes
= path
.as_os_str().as_bytes();
56 if bytes
.contains(&0) {
57 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
58 "paths may not contain interior null bytes"));
61 if bytes
.len() >= addr
.sun_path
.len() {
62 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
63 "path must be shorter than SUN_LEN"));
65 for (dst
, src
) in addr
.sun_path
.iter_mut().zip(bytes
.iter()) {
66 *dst
= *src
as libc
::c_char
;
68 // null byte for pathname addresses is already there because we zeroed the
71 let mut len
= sun_path_offset(&addr
) + bytes
.len();
76 Ok((addr
, len
as libc
::socklen_t
))
79 enum AddressKind
<'a
> {
85 /// An address associated with a Unix socket.
90 /// use std::os::unix::net::UnixListener;
92 /// let socket = match UnixListener::bind("/tmp/sock") {
95 /// println!("Couldn't bind: {:?}", e);
99 /// let addr = socket.local_addr().expect("Couldn't get local address");
102 #[stable(feature = "unix_socket", since = "1.10.0")]
103 pub struct SocketAddr
{
104 addr
: libc
::sockaddr_un
,
105 len
: libc
::socklen_t
,
109 fn new
<F
>(f
: F
) -> io
::Result
<SocketAddr
>
110 where F
: FnOnce(*mut libc
::sockaddr
, *mut libc
::socklen_t
) -> libc
::c_int
113 let mut addr
: libc
::sockaddr_un
= mem
::zeroed();
114 let mut len
= mem
::size_of
::<libc
::sockaddr_un
>() as libc
::socklen_t
;
115 cvt(f(&mut addr
as *mut _
as *mut _
, &mut len
))?
;
116 SocketAddr
::from_parts(addr
, len
)
120 fn from_parts(addr
: libc
::sockaddr_un
, mut len
: libc
::socklen_t
) -> io
::Result
<SocketAddr
> {
122 // When there is a datagram from unnamed unix socket
123 // linux returns zero bytes of address
124 len
= sun_path_offset(&addr
) as libc
::socklen_t
; // i.e., zero-length address
125 } else if addr
.sun_family
!= libc
::AF_UNIX
as libc
::sa_family_t
{
126 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
127 "file descriptor did not correspond to a Unix socket"));
136 /// Returns `true` if the address is unnamed.
143 /// use std::os::unix::net::UnixListener;
145 /// fn main() -> std::io::Result<()> {
146 /// let socket = UnixListener::bind("/tmp/sock")?;
147 /// let addr = socket.local_addr().expect("Couldn't get local address");
148 /// assert_eq!(addr.is_unnamed(), false);
153 /// An unnamed address:
156 /// use std::os::unix::net::UnixDatagram;
158 /// fn main() -> std::io::Result<()> {
159 /// let socket = UnixDatagram::unbound()?;
160 /// let addr = socket.local_addr().expect("Couldn't get local address");
161 /// assert_eq!(addr.is_unnamed(), true);
165 #[stable(feature = "unix_socket", since = "1.10.0")]
166 pub fn is_unnamed(&self) -> bool
{
167 if let AddressKind
::Unnamed
= self.address() {
174 /// Returns the contents of this address if it is a `pathname` address.
181 /// use std::os::unix::net::UnixListener;
182 /// use std::path::Path;
184 /// fn main() -> std::io::Result<()> {
185 /// let socket = UnixListener::bind("/tmp/sock")?;
186 /// let addr = socket.local_addr().expect("Couldn't get local address");
187 /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock")));
192 /// Without a pathname:
195 /// use std::os::unix::net::UnixDatagram;
197 /// fn main() -> std::io::Result<()> {
198 /// let socket = UnixDatagram::unbound()?;
199 /// let addr = socket.local_addr().expect("Couldn't get local address");
200 /// assert_eq!(addr.as_pathname(), None);
204 #[stable(feature = "unix_socket", since = "1.10.0")]
205 pub fn as_pathname(&self) -> Option
<&Path
> {
206 if let AddressKind
::Pathname(path
) = self.address() {
213 fn address(&self) -> AddressKind
<'_
> {
214 let len
= self.len
as usize - sun_path_offset(&self.addr
);
215 let path
= unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) }
;
217 // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
219 || (cfg
!(not(any(target_os
= "linux", target_os
= "android")))
220 && self.addr
.sun_path
[0] == 0)
223 } else if self.addr
.sun_path
[0] == 0 {
224 AddressKind
::Abstract(&path
[1..len
])
226 AddressKind
::Pathname(OsStr
::from_bytes(&path
[..len
- 1]).as_ref())
231 #[stable(feature = "unix_socket", since = "1.10.0")]
232 impl fmt
::Debug
for SocketAddr
{
233 fn fmt(&self, fmt
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
234 match self.address() {
235 AddressKind
::Unnamed
=> write
!(fmt
, "(unnamed)"),
236 AddressKind
::Abstract(name
) => write
!(fmt
, "{} (abstract)", AsciiEscaped(name
)),
237 AddressKind
::Pathname(path
) => write
!(fmt
, "{:?} (pathname)", path
),
242 struct AsciiEscaped
<'a
>(&'a
[u8]);
244 impl<'a
> fmt
::Display
for AsciiEscaped
<'a
> {
245 fn fmt(&self, fmt
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
247 for byte
in self.0.iter
().cloned().flat_map(ascii
::escape_default
) {
248 write
!(fmt
, "{}", byte
as char)?
;
254 /// A Unix stream socket.
259 /// use std::os::unix::net::UnixStream;
260 /// use std::io::prelude::*;
262 /// fn main() -> std::io::Result<()> {
263 /// let mut stream = UnixStream::connect("/path/to/my/socket")?;
264 /// stream.write_all(b"hello world")?;
265 /// let mut response = String::new();
266 /// stream.read_to_string(&mut response)?;
267 /// println!("{}", response);
271 #[stable(feature = "unix_socket", since = "1.10.0")]
272 pub struct UnixStream(Socket
);
274 #[stable(feature = "unix_socket", since = "1.10.0")]
275 impl fmt
::Debug
for UnixStream
{
276 fn fmt(&self, fmt
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
277 let mut builder
= fmt
.debug_struct("UnixStream");
278 builder
.field("fd", self.0.as_inner());
279 if let Ok(addr
) = self.local_addr() {
280 builder
.field("local", &addr
);
282 if let Ok(addr
) = self.peer_addr() {
283 builder
.field("peer", &addr
);
290 /// Connects to the socket named by `path`.
295 /// use std::os::unix::net::UnixStream;
297 /// let socket = match UnixStream::connect("/tmp/sock") {
298 /// Ok(sock) => sock,
300 /// println!("Couldn't connect: {:?}", e);
305 #[stable(feature = "unix_socket", since = "1.10.0")]
306 pub fn connect
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<UnixStream
> {
307 fn inner(path
: &Path
) -> io
::Result
<UnixStream
> {
309 let inner
= Socket
::new_raw(libc
::AF_UNIX
, libc
::SOCK_STREAM
)?
;
310 let (addr
, len
) = sockaddr_un(path
)?
;
312 cvt(libc
::connect(*inner
.as_inner(), &addr
as *const _
as *const _
, len
))?
;
313 Ok(UnixStream(inner
))
319 /// Creates an unnamed pair of connected sockets.
321 /// Returns two `UnixStream`s which are connected to each other.
326 /// use std::os::unix::net::UnixStream;
328 /// let (sock1, sock2) = match UnixStream::pair() {
329 /// Ok((sock1, sock2)) => (sock1, sock2),
331 /// println!("Couldn't create a pair of sockets: {:?}", e);
336 #[stable(feature = "unix_socket", since = "1.10.0")]
337 pub fn pair() -> io
::Result
<(UnixStream
, UnixStream
)> {
338 let (i1
, i2
) = Socket
::new_pair(libc
::AF_UNIX
, libc
::SOCK_STREAM
)?
;
339 Ok((UnixStream(i1
), UnixStream(i2
)))
342 /// Creates a new independently owned handle to the underlying socket.
344 /// The returned `UnixStream` is a reference to the same stream that this
345 /// object references. Both handles will read and write the same stream of
346 /// data, and options set on one stream will be propagated to the other
352 /// use std::os::unix::net::UnixStream;
354 /// fn main() -> std::io::Result<()> {
355 /// let socket = UnixStream::connect("/tmp/sock")?;
356 /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
360 #[stable(feature = "unix_socket", since = "1.10.0")]
361 pub fn try_clone(&self) -> io
::Result
<UnixStream
> {
362 self.0.duplicate().map(UnixStream
)
365 /// Returns the socket address of the local half of this connection.
370 /// use std::os::unix::net::UnixStream;
372 /// fn main() -> std::io::Result<()> {
373 /// let socket = UnixStream::connect("/tmp/sock")?;
374 /// let addr = socket.local_addr().expect("Couldn't get local address");
378 #[stable(feature = "unix_socket", since = "1.10.0")]
379 pub fn local_addr(&self) -> io
::Result
<SocketAddr
> {
380 SocketAddr
::new(|addr
, len
| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }
)
383 /// Returns the socket address of the remote half of this connection.
388 /// use std::os::unix::net::UnixStream;
390 /// fn main() -> std::io::Result<()> {
391 /// let socket = UnixStream::connect("/tmp/sock")?;
392 /// let addr = socket.peer_addr().expect("Couldn't get peer address");
396 #[stable(feature = "unix_socket", since = "1.10.0")]
397 pub fn peer_addr(&self) -> io
::Result
<SocketAddr
> {
398 SocketAddr
::new(|addr
, len
| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) }
)
401 /// Sets the read timeout for the socket.
403 /// If the provided value is [`None`], then [`read`] calls will block
404 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
407 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
408 /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
409 /// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read
410 /// [`Duration`]: ../../../../std/time/struct.Duration.html
415 /// use std::os::unix::net::UnixStream;
416 /// use std::time::Duration;
418 /// fn main() -> std::io::Result<()> {
419 /// let socket = UnixStream::connect("/tmp/sock")?;
420 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
425 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
430 /// use std::os::unix::net::UnixStream;
431 /// use std::time::Duration;
433 /// fn main() -> std::io::Result<()> {
434 /// let socket = UnixStream::connect("/tmp/sock")?;
435 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
436 /// let err = result.unwrap_err();
437 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
441 #[stable(feature = "unix_socket", since = "1.10.0")]
442 pub fn set_read_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
443 self.0.set_timeout(timeout
, libc
::SO_RCVTIMEO
)
446 /// Sets the write timeout for the socket.
448 /// If the provided value is [`None`], then [`write`] calls will block
449 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
450 /// passed to this method.
452 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
453 /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
454 /// [`write`]: ../../../../std/io/trait.Write.html#tymethod.write
455 /// [`Duration`]: ../../../../std/time/struct.Duration.html
460 /// use std::os::unix::net::UnixStream;
461 /// use std::time::Duration;
463 /// fn main() -> std::io::Result<()> {
464 /// let socket = UnixStream::connect("/tmp/sock")?;
465 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
466 /// .expect("Couldn't set write timeout");
471 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
476 /// use std::net::UdpSocket;
477 /// use std::time::Duration;
479 /// fn main() -> std::io::Result<()> {
480 /// let socket = UdpSocket::bind("127.0.0.1:34254")?;
481 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
482 /// let err = result.unwrap_err();
483 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
487 #[stable(feature = "unix_socket", since = "1.10.0")]
488 pub fn set_write_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
489 self.0.set_timeout(timeout
, libc
::SO_SNDTIMEO
)
492 /// Returns the read timeout of this socket.
497 /// use std::os::unix::net::UnixStream;
498 /// use std::time::Duration;
500 /// fn main() -> std::io::Result<()> {
501 /// let socket = UnixStream::connect("/tmp/sock")?;
502 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
503 /// assert_eq!(socket.read_timeout()?, Some(Duration::new(1, 0)));
507 #[stable(feature = "unix_socket", since = "1.10.0")]
508 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
509 self.0.timeout(libc
::SO_RCVTIMEO
)
512 /// Returns the write timeout of this socket.
517 /// use std::os::unix::net::UnixStream;
518 /// use std::time::Duration;
520 /// fn main() -> std::io::Result<()> {
521 /// let socket = UnixStream::connect("/tmp/sock")?;
522 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
523 /// .expect("Couldn't set write timeout");
524 /// assert_eq!(socket.write_timeout()?, Some(Duration::new(1, 0)));
528 #[stable(feature = "unix_socket", since = "1.10.0")]
529 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
530 self.0.timeout(libc
::SO_SNDTIMEO
)
533 /// Moves the socket into or out of nonblocking mode.
538 /// use std::os::unix::net::UnixStream;
540 /// fn main() -> std::io::Result<()> {
541 /// let socket = UnixStream::connect("/tmp/sock")?;
542 /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
546 #[stable(feature = "unix_socket", since = "1.10.0")]
547 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
548 self.0.set_nonblocking(nonblocking
)
551 /// Returns the value of the `SO_ERROR` option.
556 /// use std::os::unix::net::UnixStream;
558 /// fn main() -> std::io::Result<()> {
559 /// let socket = UnixStream::connect("/tmp/sock")?;
560 /// if let Ok(Some(err)) = socket.take_error() {
561 /// println!("Got error: {:?}", err);
567 /// # Platform specific
568 /// On Redox this always returns `None`.
569 #[stable(feature = "unix_socket", since = "1.10.0")]
570 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
574 /// Shuts down the read, write, or both halves of this connection.
576 /// This function will cause all pending and future I/O calls on the
577 /// specified portions to immediately return with an appropriate value
578 /// (see the documentation of [`Shutdown`]).
580 /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
585 /// use std::os::unix::net::UnixStream;
586 /// use std::net::Shutdown;
588 /// fn main() -> std::io::Result<()> {
589 /// let socket = UnixStream::connect("/tmp/sock")?;
590 /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
594 #[stable(feature = "unix_socket", since = "1.10.0")]
595 pub fn shutdown(&self, how
: Shutdown
) -> io
::Result
<()> {
600 #[stable(feature = "unix_socket", since = "1.10.0")]
601 impl io
::Read
for UnixStream
{
602 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
603 io
::Read
::read(&mut &*self, buf
)
606 fn read_vectored(&mut self, bufs
: &mut [IoSliceMut
<'_
>]) -> io
::Result
<usize> {
607 io
::Read
::read_vectored(&mut &*self, bufs
)
611 unsafe fn initializer(&self) -> Initializer
{
616 #[stable(feature = "unix_socket", since = "1.10.0")]
617 impl<'a
> io
::Read
for &'a UnixStream
{
618 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
622 fn read_vectored(&mut self, bufs
: &mut [IoSliceMut
<'_
>]) -> io
::Result
<usize> {
623 self.0.read_vectored(bufs
)
627 unsafe fn initializer(&self) -> Initializer
{
632 #[stable(feature = "unix_socket", since = "1.10.0")]
633 impl io
::Write
for UnixStream
{
634 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
635 io
::Write
::write(&mut &*self, buf
)
638 fn write_vectored(&mut self, bufs
: &[IoSlice
<'_
>]) -> io
::Result
<usize> {
639 io
::Write
::write_vectored(&mut &*self, bufs
)
642 fn flush(&mut self) -> io
::Result
<()> {
643 io
::Write
::flush(&mut &*self)
647 #[stable(feature = "unix_socket", since = "1.10.0")]
648 impl<'a
> io
::Write
for &'a UnixStream
{
649 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
653 fn write_vectored(&mut self, bufs
: &[IoSlice
<'_
>]) -> io
::Result
<usize> {
654 self.0.write_vectored(bufs
)
657 fn flush(&mut self) -> io
::Result
<()> {
662 #[stable(feature = "unix_socket", since = "1.10.0")]
663 impl AsRawFd
for UnixStream
{
664 fn as_raw_fd(&self) -> RawFd
{
669 #[stable(feature = "unix_socket", since = "1.10.0")]
670 impl FromRawFd
for UnixStream
{
671 unsafe fn from_raw_fd(fd
: RawFd
) -> UnixStream
{
672 UnixStream(Socket
::from_inner(fd
))
676 #[stable(feature = "unix_socket", since = "1.10.0")]
677 impl IntoRawFd
for UnixStream
{
678 fn into_raw_fd(self) -> RawFd
{
683 #[stable(feature = "rust1", since = "1.0.0")]
684 impl AsRawFd
for net
::TcpStream
{
685 fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
688 #[stable(feature = "rust1", since = "1.0.0")]
689 impl AsRawFd
for net
::TcpListener
{
690 fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
693 #[stable(feature = "rust1", since = "1.0.0")]
694 impl AsRawFd
for net
::UdpSocket
{
695 fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
698 #[stable(feature = "from_raw_os", since = "1.1.0")]
699 impl FromRawFd
for net
::TcpStream
{
700 unsafe fn from_raw_fd(fd
: RawFd
) -> net
::TcpStream
{
701 let socket
= sys
::net
::Socket
::from_inner(fd
);
702 net
::TcpStream
::from_inner(sys_common
::net
::TcpStream
::from_inner(socket
))
706 #[stable(feature = "from_raw_os", since = "1.1.0")]
707 impl FromRawFd
for net
::TcpListener
{
708 unsafe fn from_raw_fd(fd
: RawFd
) -> net
::TcpListener
{
709 let socket
= sys
::net
::Socket
::from_inner(fd
);
710 net
::TcpListener
::from_inner(sys_common
::net
::TcpListener
::from_inner(socket
))
714 #[stable(feature = "from_raw_os", since = "1.1.0")]
715 impl FromRawFd
for net
::UdpSocket
{
716 unsafe fn from_raw_fd(fd
: RawFd
) -> net
::UdpSocket
{
717 let socket
= sys
::net
::Socket
::from_inner(fd
);
718 net
::UdpSocket
::from_inner(sys_common
::net
::UdpSocket
::from_inner(socket
))
722 #[stable(feature = "into_raw_os", since = "1.4.0")]
723 impl IntoRawFd
for net
::TcpStream
{
724 fn into_raw_fd(self) -> RawFd
{
725 self.into_inner().into_socket().into_inner()
728 #[stable(feature = "into_raw_os", since = "1.4.0")]
729 impl IntoRawFd
for net
::TcpListener
{
730 fn into_raw_fd(self) -> RawFd
{
731 self.into_inner().into_socket().into_inner()
734 #[stable(feature = "into_raw_os", since = "1.4.0")]
735 impl IntoRawFd
for net
::UdpSocket
{
736 fn into_raw_fd(self) -> RawFd
{
737 self.into_inner().into_socket().into_inner()
741 /// A structure representing a Unix domain socket server.
747 /// use std::os::unix::net::{UnixStream, UnixListener};
749 /// fn handle_client(stream: UnixStream) {
753 /// fn main() -> std::io::Result<()> {
754 /// let listener = UnixListener::bind("/path/to/the/socket")?;
756 /// // accept connections and process them, spawning a new thread for each one
757 /// for stream in listener.incoming() {
760 /// /* connection succeeded */
761 /// thread::spawn(|| handle_client(stream));
764 /// /* connection failed */
772 #[stable(feature = "unix_socket", since = "1.10.0")]
773 pub struct UnixListener(Socket
);
775 #[stable(feature = "unix_socket", since = "1.10.0")]
776 impl fmt
::Debug
for UnixListener
{
777 fn fmt(&self, fmt
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
778 let mut builder
= fmt
.debug_struct("UnixListener");
779 builder
.field("fd", self.0.as_inner());
780 if let Ok(addr
) = self.local_addr() {
781 builder
.field("local", &addr
);
788 /// Creates a new `UnixListener` bound to the specified socket.
793 /// use std::os::unix::net::UnixListener;
795 /// let listener = match UnixListener::bind("/path/to/the/socket") {
796 /// Ok(sock) => sock,
798 /// println!("Couldn't connect: {:?}", e);
803 #[stable(feature = "unix_socket", since = "1.10.0")]
804 pub fn bind
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<UnixListener
> {
805 fn inner(path
: &Path
) -> io
::Result
<UnixListener
> {
807 let inner
= Socket
::new_raw(libc
::AF_UNIX
, libc
::SOCK_STREAM
)?
;
808 let (addr
, len
) = sockaddr_un(path
)?
;
810 cvt(libc
::bind(*inner
.as_inner(), &addr
as *const _
as *const _
, len
as _
))?
;
811 cvt(libc
::listen(*inner
.as_inner(), 128))?
;
813 Ok(UnixListener(inner
))
819 /// Accepts a new incoming connection to this listener.
821 /// This function will block the calling thread until a new Unix connection
822 /// is established. When established, the corresponding [`UnixStream`] and
823 /// the remote peer's address will be returned.
825 /// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html
830 /// use std::os::unix::net::UnixListener;
832 /// fn main() -> std::io::Result<()> {
833 /// let listener = UnixListener::bind("/path/to/the/socket")?;
835 /// match listener.accept() {
836 /// Ok((socket, addr)) => println!("Got a client: {:?}", addr),
837 /// Err(e) => println!("accept function failed: {:?}", e),
842 #[stable(feature = "unix_socket", since = "1.10.0")]
843 pub fn accept(&self) -> io
::Result
<(UnixStream
, SocketAddr
)> {
844 let mut storage
: libc
::sockaddr_un
= unsafe { mem::zeroed() }
;
845 let mut len
= mem
::size_of_val(&storage
) as libc
::socklen_t
;
846 let sock
= self.0.accept(&mut storage
as *mut _
as *mut _
, &mut len
)?
;
847 let addr
= SocketAddr
::from_parts(storage
, len
)?
;
848 Ok((UnixStream(sock
), addr
))
851 /// Creates a new independently owned handle to the underlying socket.
853 /// The returned `UnixListener` is a reference to the same socket that this
854 /// object references. Both handles can be used to accept incoming
855 /// connections and options set on one listener will affect the other.
860 /// use std::os::unix::net::UnixListener;
862 /// fn main() -> std::io::Result<()> {
863 /// let listener = UnixListener::bind("/path/to/the/socket")?;
864 /// let listener_copy = listener.try_clone().expect("try_clone failed");
868 #[stable(feature = "unix_socket", since = "1.10.0")]
869 pub fn try_clone(&self) -> io
::Result
<UnixListener
> {
870 self.0.duplicate().map(UnixListener
)
873 /// Returns the local socket address of this listener.
878 /// use std::os::unix::net::UnixListener;
880 /// fn main() -> std::io::Result<()> {
881 /// let listener = UnixListener::bind("/path/to/the/socket")?;
882 /// let addr = listener.local_addr().expect("Couldn't get local address");
886 #[stable(feature = "unix_socket", since = "1.10.0")]
887 pub fn local_addr(&self) -> io
::Result
<SocketAddr
> {
888 SocketAddr
::new(|addr
, len
| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }
)
891 /// Moves the socket into or out of nonblocking mode.
896 /// use std::os::unix::net::UnixListener;
898 /// fn main() -> std::io::Result<()> {
899 /// let listener = UnixListener::bind("/path/to/the/socket")?;
900 /// listener.set_nonblocking(true).expect("Couldn't set non blocking");
904 #[stable(feature = "unix_socket", since = "1.10.0")]
905 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
906 self.0.set_nonblocking(nonblocking
)
909 /// Returns the value of the `SO_ERROR` option.
914 /// use std::os::unix::net::UnixListener;
916 /// fn main() -> std::io::Result<()> {
917 /// let listener = UnixListener::bind("/tmp/sock")?;
919 /// if let Ok(Some(err)) = listener.take_error() {
920 /// println!("Got error: {:?}", err);
926 /// # Platform specific
927 /// On Redox this always returns `None`.
928 #[stable(feature = "unix_socket", since = "1.10.0")]
929 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
933 /// Returns an iterator over incoming connections.
935 /// The iterator will never return [`None`] and will also not yield the
936 /// peer's [`SocketAddr`] structure.
938 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
939 /// [`SocketAddr`]: struct.SocketAddr.html
945 /// use std::os::unix::net::{UnixStream, UnixListener};
947 /// fn handle_client(stream: UnixStream) {
951 /// fn main() -> std::io::Result<()> {
952 /// let listener = UnixListener::bind("/path/to/the/socket")?;
954 /// for stream in listener.incoming() {
957 /// thread::spawn(|| handle_client(stream));
967 #[stable(feature = "unix_socket", since = "1.10.0")]
968 pub fn incoming(&self) -> Incoming
<'_
> {
969 Incoming { listener: self }
973 #[stable(feature = "unix_socket", since = "1.10.0")]
974 impl AsRawFd
for UnixListener
{
975 fn as_raw_fd(&self) -> RawFd
{
980 #[stable(feature = "unix_socket", since = "1.10.0")]
981 impl FromRawFd
for UnixListener
{
982 unsafe fn from_raw_fd(fd
: RawFd
) -> UnixListener
{
983 UnixListener(Socket
::from_inner(fd
))
987 #[stable(feature = "unix_socket", since = "1.10.0")]
988 impl IntoRawFd
for UnixListener
{
989 fn into_raw_fd(self) -> RawFd
{
994 #[stable(feature = "unix_socket", since = "1.10.0")]
995 impl<'a
> IntoIterator
for &'a UnixListener
{
996 type Item
= io
::Result
<UnixStream
>;
997 type IntoIter
= Incoming
<'a
>;
999 fn into_iter(self) -> Incoming
<'a
> {
1004 /// An iterator over incoming connections to a [`UnixListener`].
1006 /// It will never return [`None`].
1008 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
1009 /// [`UnixListener`]: struct.UnixListener.html
1014 /// use std::thread;
1015 /// use std::os::unix::net::{UnixStream, UnixListener};
1017 /// fn handle_client(stream: UnixStream) {
1021 /// fn main() -> std::io::Result<()> {
1022 /// let listener = UnixListener::bind("/path/to/the/socket")?;
1024 /// for stream in listener.incoming() {
1027 /// thread::spawn(|| handle_client(stream));
1038 #[stable(feature = "unix_socket", since = "1.10.0")]
1039 pub struct Incoming
<'a
> {
1040 listener
: &'a UnixListener
,
1043 #[stable(feature = "unix_socket", since = "1.10.0")]
1044 impl<'a
> Iterator
for Incoming
<'a
> {
1045 type Item
= io
::Result
<UnixStream
>;
1047 fn next(&mut self) -> Option
<io
::Result
<UnixStream
>> {
1048 Some(self.listener
.accept().map(|s
| s
.0))
1051 fn size_hint(&self) -> (usize, Option
<usize>) {
1052 (usize::max_value(), None
)
1056 /// A Unix datagram socket.
1061 /// use std::os::unix::net::UnixDatagram;
1063 /// fn main() -> std::io::Result<()> {
1064 /// let socket = UnixDatagram::bind("/path/to/my/socket")?;
1065 /// socket.send_to(b"hello world", "/path/to/other/socket")?;
1066 /// let mut buf = [0; 100];
1067 /// let (count, address) = socket.recv_from(&mut buf)?;
1068 /// println!("socket {:?} sent {:?}", address, &buf[..count]);
1072 #[stable(feature = "unix_socket", since = "1.10.0")]
1073 pub struct UnixDatagram(Socket
);
1075 #[stable(feature = "unix_socket", since = "1.10.0")]
1076 impl fmt
::Debug
for UnixDatagram
{
1077 fn fmt(&self, fmt
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1078 let mut builder
= fmt
.debug_struct("UnixDatagram");
1079 builder
.field("fd", self.0.as_inner());
1080 if let Ok(addr
) = self.local_addr() {
1081 builder
.field("local", &addr
);
1083 if let Ok(addr
) = self.peer_addr() {
1084 builder
.field("peer", &addr
);
1091 /// Creates a Unix datagram socket bound to the given path.
1096 /// use std::os::unix::net::UnixDatagram;
1098 /// let sock = match UnixDatagram::bind("/path/to/the/socket") {
1099 /// Ok(sock) => sock,
1101 /// println!("Couldn't bind: {:?}", e);
1106 #[stable(feature = "unix_socket", since = "1.10.0")]
1107 pub fn bind
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<UnixDatagram
> {
1108 fn inner(path
: &Path
) -> io
::Result
<UnixDatagram
> {
1110 let socket
= UnixDatagram
::unbound()?
;
1111 let (addr
, len
) = sockaddr_un(path
)?
;
1113 cvt(libc
::bind(*socket
.0.as_inner(), &addr
as *const _
as *const _
, len
as _
))?
;
1118 inner(path
.as_ref())
1121 /// Creates a Unix Datagram socket which is not bound to any address.
1126 /// use std::os::unix::net::UnixDatagram;
1128 /// let sock = match UnixDatagram::unbound() {
1129 /// Ok(sock) => sock,
1131 /// println!("Couldn't unbound: {:?}", e);
1136 #[stable(feature = "unix_socket", since = "1.10.0")]
1137 pub fn unbound() -> io
::Result
<UnixDatagram
> {
1138 let inner
= Socket
::new_raw(libc
::AF_UNIX
, libc
::SOCK_DGRAM
)?
;
1139 Ok(UnixDatagram(inner
))
1142 /// Creates an unnamed pair of connected sockets.
1144 /// Returns two `UnixDatagrams`s which are connected to each other.
1149 /// use std::os::unix::net::UnixDatagram;
1151 /// let (sock1, sock2) = match UnixDatagram::pair() {
1152 /// Ok((sock1, sock2)) => (sock1, sock2),
1154 /// println!("Couldn't unbound: {:?}", e);
1159 #[stable(feature = "unix_socket", since = "1.10.0")]
1160 pub fn pair() -> io
::Result
<(UnixDatagram
, UnixDatagram
)> {
1161 let (i1
, i2
) = Socket
::new_pair(libc
::AF_UNIX
, libc
::SOCK_DGRAM
)?
;
1162 Ok((UnixDatagram(i1
), UnixDatagram(i2
)))
1165 /// Connects the socket to the specified address.
1167 /// The [`send`] method may be used to send data to the specified address.
1168 /// [`recv`] and [`recv_from`] will only receive data from that address.
1170 /// [`send`]: #method.send
1171 /// [`recv`]: #method.recv
1172 /// [`recv_from`]: #method.recv_from
1177 /// use std::os::unix::net::UnixDatagram;
1179 /// fn main() -> std::io::Result<()> {
1180 /// let sock = UnixDatagram::unbound()?;
1181 /// match sock.connect("/path/to/the/socket") {
1182 /// Ok(sock) => sock,
1184 /// println!("Couldn't connect: {:?}", e);
1191 #[stable(feature = "unix_socket", since = "1.10.0")]
1192 pub fn connect
<P
: AsRef
<Path
>>(&self, path
: P
) -> io
::Result
<()> {
1193 fn inner(d
: &UnixDatagram
, path
: &Path
) -> io
::Result
<()> {
1195 let (addr
, len
) = sockaddr_un(path
)?
;
1197 cvt(libc
::connect(*d
.0.as_inner(), &addr
as *const _
as *const _
, len
))?
;
1202 inner(self, path
.as_ref())
1205 /// Creates a new independently owned handle to the underlying socket.
1207 /// The returned `UnixDatagram` is a reference to the same socket that this
1208 /// object references. Both handles can be used to accept incoming
1209 /// connections and options set on one side will affect the other.
1214 /// use std::os::unix::net::UnixDatagram;
1216 /// fn main() -> std::io::Result<()> {
1217 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
1218 /// let sock_copy = sock.try_clone().expect("try_clone failed");
1222 #[stable(feature = "unix_socket", since = "1.10.0")]
1223 pub fn try_clone(&self) -> io
::Result
<UnixDatagram
> {
1224 self.0.duplicate().map(UnixDatagram
)
1227 /// Returns the address of this socket.
1232 /// use std::os::unix::net::UnixDatagram;
1234 /// fn main() -> std::io::Result<()> {
1235 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
1236 /// let addr = sock.local_addr().expect("Couldn't get local address");
1240 #[stable(feature = "unix_socket", since = "1.10.0")]
1241 pub fn local_addr(&self) -> io
::Result
<SocketAddr
> {
1242 SocketAddr
::new(|addr
, len
| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }
)
1245 /// Returns the address of this socket's peer.
1247 /// The [`connect`] method will connect the socket to a peer.
1249 /// [`connect`]: #method.connect
1254 /// use std::os::unix::net::UnixDatagram;
1256 /// fn main() -> std::io::Result<()> {
1257 /// let sock = UnixDatagram::unbound()?;
1258 /// sock.connect("/path/to/the/socket")?;
1260 /// let addr = sock.peer_addr().expect("Couldn't get peer address");
1264 #[stable(feature = "unix_socket", since = "1.10.0")]
1265 pub fn peer_addr(&self) -> io
::Result
<SocketAddr
> {
1266 SocketAddr
::new(|addr
, len
| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) }
)
1269 /// Receives data from the socket.
1271 /// On success, returns the number of bytes read and the address from
1272 /// whence the data came.
1277 /// use std::os::unix::net::UnixDatagram;
1279 /// fn main() -> std::io::Result<()> {
1280 /// let sock = UnixDatagram::unbound()?;
1281 /// let mut buf = vec![0; 10];
1282 /// let (size, sender) = sock.recv_from(buf.as_mut_slice())?;
1283 /// println!("received {} bytes from {:?}", size, sender);
1287 #[stable(feature = "unix_socket", since = "1.10.0")]
1288 pub fn recv_from(&self, buf
: &mut [u8]) -> io
::Result
<(usize, SocketAddr
)> {
1290 let addr
= SocketAddr
::new(|addr
, len
| {
1292 count
= libc
::recvfrom(*self.0.as_inner(),
1293 buf
.as_mut_ptr() as *mut _
,
1300 } else if count
== 0 {
1308 Ok((count
as usize, addr
))
1311 /// Receives data from the socket.
1313 /// On success, returns the number of bytes read.
1318 /// use std::os::unix::net::UnixDatagram;
1320 /// fn main() -> std::io::Result<()> {
1321 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
1322 /// let mut buf = vec![0; 10];
1323 /// sock.recv(buf.as_mut_slice()).expect("recv function failed");
1327 #[stable(feature = "unix_socket", since = "1.10.0")]
1328 pub fn recv(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
1332 /// Sends data on the socket to the specified address.
1334 /// On success, returns the number of bytes written.
1339 /// use std::os::unix::net::UnixDatagram;
1341 /// fn main() -> std::io::Result<()> {
1342 /// let sock = UnixDatagram::unbound()?;
1343 /// sock.send_to(b"omelette au fromage", "/some/sock").expect("send_to function failed");
1347 #[stable(feature = "unix_socket", since = "1.10.0")]
1348 pub fn send_to
<P
: AsRef
<Path
>>(&self, buf
: &[u8], path
: P
) -> io
::Result
<usize> {
1349 fn inner(d
: &UnixDatagram
, buf
: &[u8], path
: &Path
) -> io
::Result
<usize> {
1351 let (addr
, len
) = sockaddr_un(path
)?
;
1353 let count
= cvt(libc
::sendto(*d
.0.as_inner(),
1354 buf
.as_ptr() as *const _
,
1357 &addr
as *const _
as *const _
,
1362 inner(self, buf
, path
.as_ref())
1365 /// Sends data on the socket to the socket's peer.
1367 /// The peer address may be set by the `connect` method, and this method
1368 /// will return an error if the socket has not already been connected.
1370 /// On success, returns the number of bytes written.
1375 /// use std::os::unix::net::UnixDatagram;
1377 /// fn main() -> std::io::Result<()> {
1378 /// let sock = UnixDatagram::unbound()?;
1379 /// sock.connect("/some/sock").expect("Couldn't connect");
1380 /// sock.send(b"omelette au fromage").expect("send_to function failed");
1384 #[stable(feature = "unix_socket", since = "1.10.0")]
1385 pub fn send(&self, buf
: &[u8]) -> io
::Result
<usize> {
1389 /// Sets the read timeout for the socket.
1391 /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will
1392 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`]
1393 /// is passed to this method.
1395 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
1396 /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
1397 /// [`recv`]: #method.recv
1398 /// [`recv_from`]: #method.recv_from
1399 /// [`Duration`]: ../../../../std/time/struct.Duration.html
1404 /// use std::os::unix::net::UnixDatagram;
1405 /// use std::time::Duration;
1407 /// fn main() -> std::io::Result<()> {
1408 /// let sock = UnixDatagram::unbound()?;
1409 /// sock.set_read_timeout(Some(Duration::new(1, 0)))
1410 /// .expect("set_read_timeout function failed");
1415 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
1420 /// use std::os::unix::net::UnixDatagram;
1421 /// use std::time::Duration;
1423 /// fn main() -> std::io::Result<()> {
1424 /// let socket = UnixDatagram::unbound()?;
1425 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
1426 /// let err = result.unwrap_err();
1427 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
1431 #[stable(feature = "unix_socket", since = "1.10.0")]
1432 pub fn set_read_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
1433 self.0.set_timeout(timeout
, libc
::SO_RCVTIMEO
)
1436 /// Sets the write timeout for the socket.
1438 /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will
1439 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
1442 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
1443 /// [`send`]: #method.send
1444 /// [`send_to`]: #method.send_to
1445 /// [`Duration`]: ../../../../std/time/struct.Duration.html
1450 /// use std::os::unix::net::UnixDatagram;
1451 /// use std::time::Duration;
1453 /// fn main() -> std::io::Result<()> {
1454 /// let sock = UnixDatagram::unbound()?;
1455 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
1456 /// .expect("set_write_timeout function failed");
1461 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
1466 /// use std::os::unix::net::UnixDatagram;
1467 /// use std::time::Duration;
1469 /// fn main() -> std::io::Result<()> {
1470 /// let socket = UnixDatagram::unbound()?;
1471 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
1472 /// let err = result.unwrap_err();
1473 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
1477 #[stable(feature = "unix_socket", since = "1.10.0")]
1478 pub fn set_write_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
1479 self.0.set_timeout(timeout
, libc
::SO_SNDTIMEO
)
1482 /// Returns the read timeout of this socket.
1487 /// use std::os::unix::net::UnixDatagram;
1488 /// use std::time::Duration;
1490 /// fn main() -> std::io::Result<()> {
1491 /// let sock = UnixDatagram::unbound()?;
1492 /// sock.set_read_timeout(Some(Duration::new(1, 0)))
1493 /// .expect("set_read_timeout function failed");
1494 /// assert_eq!(sock.read_timeout()?, Some(Duration::new(1, 0)));
1498 #[stable(feature = "unix_socket", since = "1.10.0")]
1499 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
1500 self.0.timeout(libc
::SO_RCVTIMEO
)
1503 /// Returns the write timeout of this socket.
1508 /// use std::os::unix::net::UnixDatagram;
1509 /// use std::time::Duration;
1511 /// fn main() -> std::io::Result<()> {
1512 /// let sock = UnixDatagram::unbound()?;
1513 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
1514 /// .expect("set_write_timeout function failed");
1515 /// assert_eq!(sock.write_timeout()?, Some(Duration::new(1, 0)));
1519 #[stable(feature = "unix_socket", since = "1.10.0")]
1520 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
1521 self.0.timeout(libc
::SO_SNDTIMEO
)
1524 /// Moves the socket into or out of nonblocking mode.
1529 /// use std::os::unix::net::UnixDatagram;
1531 /// fn main() -> std::io::Result<()> {
1532 /// let sock = UnixDatagram::unbound()?;
1533 /// sock.set_nonblocking(true).expect("set_nonblocking function failed");
1537 #[stable(feature = "unix_socket", since = "1.10.0")]
1538 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
1539 self.0.set_nonblocking(nonblocking
)
1542 /// Returns the value of the `SO_ERROR` option.
1547 /// use std::os::unix::net::UnixDatagram;
1549 /// fn main() -> std::io::Result<()> {
1550 /// let sock = UnixDatagram::unbound()?;
1551 /// if let Ok(Some(err)) = sock.take_error() {
1552 /// println!("Got error: {:?}", err);
1557 #[stable(feature = "unix_socket", since = "1.10.0")]
1558 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
1562 /// Shut down the read, write, or both halves of this connection.
1564 /// This function will cause all pending and future I/O calls on the
1565 /// specified portions to immediately return with an appropriate value
1566 /// (see the documentation of [`Shutdown`]).
1568 /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
1571 /// use std::os::unix::net::UnixDatagram;
1572 /// use std::net::Shutdown;
1574 /// fn main() -> std::io::Result<()> {
1575 /// let sock = UnixDatagram::unbound()?;
1576 /// sock.shutdown(Shutdown::Both).expect("shutdown function failed");
1580 #[stable(feature = "unix_socket", since = "1.10.0")]
1581 pub fn shutdown(&self, how
: Shutdown
) -> io
::Result
<()> {
1582 self.0.shutdown(how
)
1586 #[stable(feature = "unix_socket", since = "1.10.0")]
1587 impl AsRawFd
for UnixDatagram
{
1588 fn as_raw_fd(&self) -> RawFd
{
1593 #[stable(feature = "unix_socket", since = "1.10.0")]
1594 impl FromRawFd
for UnixDatagram
{
1595 unsafe fn from_raw_fd(fd
: RawFd
) -> UnixDatagram
{
1596 UnixDatagram(Socket
::from_inner(fd
))
1600 #[stable(feature = "unix_socket", since = "1.10.0")]
1601 impl IntoRawFd
for UnixDatagram
{
1602 fn into_raw_fd(self) -> RawFd
{
1607 #[cfg(all(test, not(target_os = "emscripten")))]
1610 use crate::io
::{self, ErrorKind}
;
1611 use crate::io
::prelude
::*;
1612 use crate::time
::Duration
;
1613 use crate::sys_common
::io
::test
::tmpdir
;
1617 macro_rules
! or_panic
{
1621 Err(e
) => panic
!("{}", e
),
1629 let socket_path
= dir
.path().join("sock");
1630 let msg1
= b
"hello";
1631 let msg2
= b
"world!";
1633 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1634 let thread
= thread
::spawn(move || {
1635 let mut stream
= or_panic
!(listener
.accept()).0;
1636 let mut buf
= [0; 5];
1637 or_panic
!(stream
.read(&mut buf
));
1638 assert_eq
!(&msg1
[..], &buf
[..]);
1639 or_panic
!(stream
.write_all(msg2
));
1642 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1643 assert_eq
!(Some(&*socket_path
),
1644 stream
.peer_addr().unwrap().as_pathname());
1645 or_panic
!(stream
.write_all(msg1
));
1646 let mut buf
= vec
![];
1647 or_panic
!(stream
.read_to_end(&mut buf
));
1648 assert_eq
!(&msg2
[..], &buf
[..]);
1651 thread
.join().unwrap();
1656 let (mut s1
, mut s2
) = or_panic
!(UnixStream
::pair());
1658 let len
= or_panic
!(s1
.write_vectored(
1659 &[IoSlice
::new(b
"hello"), IoSlice
::new(b
" "), IoSlice
::new(b
"world!")],
1661 assert_eq
!(len
, 12);
1663 let mut buf1
= [0; 6];
1664 let mut buf2
= [0; 7];
1665 let len
= or_panic
!(s2
.read_vectored(
1666 &mut [IoSliceMut
::new(&mut buf1
), IoSliceMut
::new(&mut buf2
)],
1668 assert_eq
!(len
, 12);
1669 assert_eq
!(&buf1
, b
"hello ");
1670 assert_eq
!(&buf2
, b
"world!\0");
1675 let msg1
= b
"hello";
1676 let msg2
= b
"world!";
1678 let (mut s1
, mut s2
) = or_panic
!(UnixStream
::pair());
1679 let thread
= thread
::spawn(move || {
1680 // s1 must be moved in or the test will hang!
1681 let mut buf
= [0; 5];
1682 or_panic
!(s1
.read(&mut buf
));
1683 assert_eq
!(&msg1
[..], &buf
[..]);
1684 or_panic
!(s1
.write_all(msg2
));
1687 or_panic
!(s2
.write_all(msg1
));
1688 let mut buf
= vec
![];
1689 or_panic
!(s2
.read_to_end(&mut buf
));
1690 assert_eq
!(&msg2
[..], &buf
[..]);
1693 thread
.join().unwrap();
1699 let socket_path
= dir
.path().join("sock");
1700 let msg1
= b
"hello";
1701 let msg2
= b
"world";
1703 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1704 let thread
= thread
::spawn(move || {
1705 let mut stream
= or_panic
!(listener
.accept()).0;
1706 or_panic
!(stream
.write_all(msg1
));
1707 or_panic
!(stream
.write_all(msg2
));
1710 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1711 let mut stream2
= or_panic
!(stream
.try_clone());
1713 let mut buf
= [0; 5];
1714 or_panic
!(stream
.read(&mut buf
));
1715 assert_eq
!(&msg1
[..], &buf
[..]);
1716 or_panic
!(stream2
.read(&mut buf
));
1717 assert_eq
!(&msg2
[..], &buf
[..]);
1719 thread
.join().unwrap();
1725 let socket_path
= dir
.path().join("sock");
1727 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1728 let thread
= thread
::spawn(move || {
1729 for stream
in listener
.incoming().take(2) {
1730 let mut stream
= or_panic
!(stream
);
1732 or_panic
!(stream
.read(&mut buf
));
1737 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1738 or_panic
!(stream
.write_all(&[0]));
1741 thread
.join().unwrap();
1747 let socket_path
= dir
.path()
1748 .join("asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\
1749 sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf");
1750 match UnixStream
::connect(&socket_path
) {
1751 Err(ref e
) if e
.kind() == io
::ErrorKind
::InvalidInput
=> {}
1752 Err(e
) => panic
!("unexpected error {}", e
),
1753 Ok(_
) => panic
!("unexpected success"),
1756 match UnixListener
::bind(&socket_path
) {
1757 Err(ref e
) if e
.kind() == io
::ErrorKind
::InvalidInput
=> {}
1758 Err(e
) => panic
!("unexpected error {}", e
),
1759 Ok(_
) => panic
!("unexpected success"),
1762 match UnixDatagram
::bind(&socket_path
) {
1763 Err(ref e
) if e
.kind() == io
::ErrorKind
::InvalidInput
=> {}
1764 Err(e
) => panic
!("unexpected error {}", e
),
1765 Ok(_
) => panic
!("unexpected success"),
1772 let socket_path
= dir
.path().join("sock");
1774 let _listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1776 let stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1777 let dur
= Duration
::new(15410, 0);
1779 assert_eq
!(None
, or_panic
!(stream
.read_timeout()));
1781 or_panic
!(stream
.set_read_timeout(Some(dur
)));
1782 assert_eq
!(Some(dur
), or_panic
!(stream
.read_timeout()));
1784 assert_eq
!(None
, or_panic
!(stream
.write_timeout()));
1786 or_panic
!(stream
.set_write_timeout(Some(dur
)));
1787 assert_eq
!(Some(dur
), or_panic
!(stream
.write_timeout()));
1789 or_panic
!(stream
.set_read_timeout(None
));
1790 assert_eq
!(None
, or_panic
!(stream
.read_timeout()));
1792 or_panic
!(stream
.set_write_timeout(None
));
1793 assert_eq
!(None
, or_panic
!(stream
.write_timeout()));
1797 fn test_read_timeout() {
1799 let socket_path
= dir
.path().join("sock");
1801 let _listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1803 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1804 or_panic
!(stream
.set_read_timeout(Some(Duration
::from_millis(1000))));
1806 let mut buf
= [0; 10];
1807 let kind
= stream
.read_exact(&mut buf
).err().expect("expected error").kind();
1808 assert
!(kind
== ErrorKind
::WouldBlock
|| kind
== ErrorKind
::TimedOut
,
1809 "unexpected_error: {:?}", kind
);
1813 fn test_read_with_timeout() {
1815 let socket_path
= dir
.path().join("sock");
1817 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1819 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1820 or_panic
!(stream
.set_read_timeout(Some(Duration
::from_millis(1000))));
1822 let mut other_end
= or_panic
!(listener
.accept()).0;
1823 or_panic
!(other_end
.write_all(b
"hello world"));
1825 let mut buf
= [0; 11];
1826 or_panic
!(stream
.read(&mut buf
));
1827 assert_eq
!(b
"hello world", &buf
[..]);
1829 let kind
= stream
.read_exact(&mut buf
).err().expect("expected error").kind();
1830 assert
!(kind
== ErrorKind
::WouldBlock
|| kind
== ErrorKind
::TimedOut
,
1831 "unexpected_error: {:?}", kind
);
1834 // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
1835 // when passed zero Durations
1837 fn test_unix_stream_timeout_zero_duration() {
1839 let socket_path
= dir
.path().join("sock");
1841 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1842 let stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1844 let result
= stream
.set_write_timeout(Some(Duration
::new(0, 0)));
1845 let err
= result
.unwrap_err();
1846 assert_eq
!(err
.kind(), ErrorKind
::InvalidInput
);
1848 let result
= stream
.set_read_timeout(Some(Duration
::new(0, 0)));
1849 let err
= result
.unwrap_err();
1850 assert_eq
!(err
.kind(), ErrorKind
::InvalidInput
);
1856 fn test_unix_datagram() {
1858 let path1
= dir
.path().join("sock1");
1859 let path2
= dir
.path().join("sock2");
1861 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
1862 let sock2
= or_panic
!(UnixDatagram
::bind(&path2
));
1864 let msg
= b
"hello world";
1865 or_panic
!(sock1
.send_to(msg
, &path2
));
1866 let mut buf
= [0; 11];
1867 or_panic
!(sock2
.recv_from(&mut buf
));
1868 assert_eq
!(msg
, &buf
[..]);
1872 fn test_unnamed_unix_datagram() {
1874 let path1
= dir
.path().join("sock1");
1876 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
1877 let sock2
= or_panic
!(UnixDatagram
::unbound());
1879 let msg
= b
"hello world";
1880 or_panic
!(sock2
.send_to(msg
, &path1
));
1881 let mut buf
= [0; 11];
1882 let (usize, addr
) = or_panic
!(sock1
.recv_from(&mut buf
));
1883 assert_eq
!(usize, 11);
1884 assert
!(addr
.is_unnamed());
1885 assert_eq
!(msg
, &buf
[..]);
1889 fn test_connect_unix_datagram() {
1891 let path1
= dir
.path().join("sock1");
1892 let path2
= dir
.path().join("sock2");
1894 let bsock1
= or_panic
!(UnixDatagram
::bind(&path1
));
1895 let bsock2
= or_panic
!(UnixDatagram
::bind(&path2
));
1896 let sock
= or_panic
!(UnixDatagram
::unbound());
1897 or_panic
!(sock
.connect(&path1
));
1900 let msg
= b
"hello there";
1901 or_panic
!(sock
.send(msg
));
1902 let mut buf
= [0; 11];
1903 let (usize, addr
) = or_panic
!(bsock1
.recv_from(&mut buf
));
1904 assert_eq
!(usize, 11);
1905 assert
!(addr
.is_unnamed());
1906 assert_eq
!(msg
, &buf
[..]);
1908 // Changing default socket works too
1909 or_panic
!(sock
.connect(&path2
));
1910 or_panic
!(sock
.send(msg
));
1911 or_panic
!(bsock2
.recv_from(&mut buf
));
1915 fn test_unix_datagram_recv() {
1917 let path1
= dir
.path().join("sock1");
1919 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
1920 let sock2
= or_panic
!(UnixDatagram
::unbound());
1921 or_panic
!(sock2
.connect(&path1
));
1923 let msg
= b
"hello world";
1924 or_panic
!(sock2
.send(msg
));
1925 let mut buf
= [0; 11];
1926 let size
= or_panic
!(sock1
.recv(&mut buf
));
1927 assert_eq
!(size
, 11);
1928 assert_eq
!(msg
, &buf
[..]);
1932 fn datagram_pair() {
1933 let msg1
= b
"hello";
1934 let msg2
= b
"world!";
1936 let (s1
, s2
) = or_panic
!(UnixDatagram
::pair());
1937 let thread
= thread
::spawn(move || {
1938 // s1 must be moved in or the test will hang!
1939 let mut buf
= [0; 5];
1940 or_panic
!(s1
.recv(&mut buf
));
1941 assert_eq
!(&msg1
[..], &buf
[..]);
1942 or_panic
!(s1
.send(msg2
));
1945 or_panic
!(s2
.send(msg1
));
1946 let mut buf
= [0; 6];
1947 or_panic
!(s2
.recv(&mut buf
));
1948 assert_eq
!(&msg2
[..], &buf
[..]);
1951 thread
.join().unwrap();
1954 // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
1955 // when passed zero Durations
1957 fn test_unix_datagram_timeout_zero_duration() {
1959 let path
= dir
.path().join("sock");
1961 let datagram
= or_panic
!(UnixDatagram
::bind(&path
));
1963 let result
= datagram
.set_write_timeout(Some(Duration
::new(0, 0)));
1964 let err
= result
.unwrap_err();
1965 assert_eq
!(err
.kind(), ErrorKind
::InvalidInput
);
1967 let result
= datagram
.set_read_timeout(Some(Duration
::new(0, 0)));
1968 let err
= result
.unwrap_err();
1969 assert_eq
!(err
.kind(), ErrorKind
::InvalidInput
);
1973 fn abstract_namespace_not_allowed() {
1974 assert
!(UnixStream
::connect("\0asdf").is_err());