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
;
21 use io
::{self, Initializer, IoVec, IoVecMut}
;
23 use net
::{self, Shutdown}
;
24 use os
::unix
::ffi
::OsStrExt
;
25 use os
::unix
::io
::{RawFd, AsRawFd, FromRawFd, IntoRawFd}
;
30 use 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", target_os
= "bitrig"))]
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", target_os
= "bitrig")))]
41 const MSG_NOSIGNAL
: libc
::c_int
= 0x0;
43 fn sun_path_offset() -> usize {
44 // Work with an actual instance of the type since using a null pointer is UB
45 let addr
: libc
::sockaddr_un
= unsafe { mem::uninitialized() }
;
46 let base
= &addr
as *const _
as usize;
47 let path
= &addr
.sun_path
as *const _
as usize;
51 unsafe fn sockaddr_un(path
: &Path
) -> io
::Result
<(libc
::sockaddr_un
, libc
::socklen_t
)> {
52 let mut addr
: libc
::sockaddr_un
= mem
::zeroed();
53 addr
.sun_family
= libc
::AF_UNIX
as libc
::sa_family_t
;
55 let bytes
= path
.as_os_str().as_bytes();
57 if bytes
.contains(&0) {
58 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
59 "paths may not contain interior null bytes"));
62 if bytes
.len() >= addr
.sun_path
.len() {
63 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
64 "path must be shorter than SUN_LEN"));
66 for (dst
, src
) in addr
.sun_path
.iter_mut().zip(bytes
.iter()) {
67 *dst
= *src
as libc
::c_char
;
69 // null byte for pathname addresses is already there because we zeroed the
72 let mut len
= sun_path_offset() + bytes
.len();
77 Ok((addr
, len
as libc
::socklen_t
))
80 enum AddressKind
<'a
> {
86 /// An address associated with a Unix socket.
91 /// use std::os::unix::net::UnixListener;
93 /// let socket = match UnixListener::bind("/tmp/sock") {
96 /// println!("Couldn't bind: {:?}", e);
100 /// let addr = socket.local_addr().expect("Couldn't get local address");
103 #[stable(feature = "unix_socket", since = "1.10.0")]
104 pub struct SocketAddr
{
105 addr
: libc
::sockaddr_un
,
106 len
: libc
::socklen_t
,
110 fn new
<F
>(f
: F
) -> io
::Result
<SocketAddr
>
111 where F
: FnOnce(*mut libc
::sockaddr
, *mut libc
::socklen_t
) -> libc
::c_int
114 let mut addr
: libc
::sockaddr_un
= mem
::zeroed();
115 let mut len
= mem
::size_of
::<libc
::sockaddr_un
>() as libc
::socklen_t
;
116 cvt(f(&mut addr
as *mut _
as *mut _
, &mut len
))?
;
117 SocketAddr
::from_parts(addr
, len
)
121 fn from_parts(addr
: libc
::sockaddr_un
, mut len
: libc
::socklen_t
) -> io
::Result
<SocketAddr
> {
123 // When there is a datagram from unnamed unix socket
124 // linux returns zero bytes of address
125 len
= sun_path_offset() as libc
::socklen_t
; // i.e., zero-length address
126 } else if addr
.sun_family
!= libc
::AF_UNIX
as libc
::sa_family_t
{
127 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
128 "file descriptor did not correspond to a Unix socket"));
137 /// Returns `true` if the address is unnamed.
144 /// use std::os::unix::net::UnixListener;
146 /// let socket = UnixListener::bind("/tmp/sock").unwrap();
147 /// let addr = socket.local_addr().expect("Couldn't get local address");
148 /// assert_eq!(addr.is_unnamed(), false);
151 /// An unnamed address:
154 /// use std::os::unix::net::UnixDatagram;
156 /// let socket = UnixDatagram::unbound().unwrap();
157 /// let addr = socket.local_addr().expect("Couldn't get local address");
158 /// assert_eq!(addr.is_unnamed(), true);
160 #[stable(feature = "unix_socket", since = "1.10.0")]
161 pub fn is_unnamed(&self) -> bool
{
162 if let AddressKind
::Unnamed
= self.address() {
169 /// Returns the contents of this address if it is a `pathname` address.
176 /// use std::os::unix::net::UnixListener;
177 /// use std::path::Path;
179 /// let socket = UnixListener::bind("/tmp/sock").unwrap();
180 /// let addr = socket.local_addr().expect("Couldn't get local address");
181 /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock")));
184 /// Without a pathname:
187 /// use std::os::unix::net::UnixDatagram;
189 /// let socket = UnixDatagram::unbound().unwrap();
190 /// let addr = socket.local_addr().expect("Couldn't get local address");
191 /// assert_eq!(addr.as_pathname(), None);
193 #[stable(feature = "unix_socket", since = "1.10.0")]
194 pub fn as_pathname(&self) -> Option
<&Path
> {
195 if let AddressKind
::Pathname(path
) = self.address() {
202 fn address
<'a
>(&'a
self) -> AddressKind
<'a
> {
203 let len
= self.len
as usize - sun_path_offset();
204 let path
= unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) }
;
206 // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
208 || (cfg
!(not(any(target_os
= "linux", target_os
= "android")))
209 && self.addr
.sun_path
[0] == 0)
212 } else if self.addr
.sun_path
[0] == 0 {
213 AddressKind
::Abstract(&path
[1..len
])
215 AddressKind
::Pathname(OsStr
::from_bytes(&path
[..len
- 1]).as_ref())
220 #[stable(feature = "unix_socket", since = "1.10.0")]
221 impl fmt
::Debug
for SocketAddr
{
222 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
223 match self.address() {
224 AddressKind
::Unnamed
=> write
!(fmt
, "(unnamed)"),
225 AddressKind
::Abstract(name
) => write
!(fmt
, "{} (abstract)", AsciiEscaped(name
)),
226 AddressKind
::Pathname(path
) => write
!(fmt
, "{:?} (pathname)", path
),
231 struct AsciiEscaped
<'a
>(&'a
[u8]);
233 impl<'a
> fmt
::Display
for AsciiEscaped
<'a
> {
234 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
236 for byte
in self.0.iter
().cloned().flat_map(ascii
::escape_default
) {
237 write
!(fmt
, "{}", byte
as char)?
;
243 /// A Unix stream socket.
248 /// use std::os::unix::net::UnixStream;
249 /// use std::io::prelude::*;
251 /// let mut stream = UnixStream::connect("/path/to/my/socket").unwrap();
252 /// stream.write_all(b"hello world").unwrap();
253 /// let mut response = String::new();
254 /// stream.read_to_string(&mut response).unwrap();
255 /// println!("{}", response);
257 #[stable(feature = "unix_socket", since = "1.10.0")]
258 pub struct UnixStream(Socket
);
260 #[stable(feature = "unix_socket", since = "1.10.0")]
261 impl fmt
::Debug
for UnixStream
{
262 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
263 let mut builder
= fmt
.debug_struct("UnixStream");
264 builder
.field("fd", self.0.as_inner());
265 if let Ok(addr
) = self.local_addr() {
266 builder
.field("local", &addr
);
268 if let Ok(addr
) = self.peer_addr() {
269 builder
.field("peer", &addr
);
276 /// Connects to the socket named by `path`.
281 /// use std::os::unix::net::UnixStream;
283 /// let socket = match UnixStream::connect("/tmp/sock") {
284 /// Ok(sock) => sock,
286 /// println!("Couldn't connect: {:?}", e);
291 #[stable(feature = "unix_socket", since = "1.10.0")]
292 pub fn connect
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<UnixStream
> {
293 fn inner(path
: &Path
) -> io
::Result
<UnixStream
> {
295 let inner
= Socket
::new_raw(libc
::AF_UNIX
, libc
::SOCK_STREAM
)?
;
296 let (addr
, len
) = sockaddr_un(path
)?
;
298 cvt(libc
::connect(*inner
.as_inner(), &addr
as *const _
as *const _
, len
))?
;
299 Ok(UnixStream(inner
))
305 /// Creates an unnamed pair of connected sockets.
307 /// Returns two `UnixStream`s which are connected to each other.
312 /// use std::os::unix::net::UnixStream;
314 /// let (sock1, sock2) = match UnixStream::pair() {
315 /// Ok((sock1, sock2)) => (sock1, sock2),
317 /// println!("Couldn't create a pair of sockets: {:?}", e);
322 #[stable(feature = "unix_socket", since = "1.10.0")]
323 pub fn pair() -> io
::Result
<(UnixStream
, UnixStream
)> {
324 let (i1
, i2
) = Socket
::new_pair(libc
::AF_UNIX
, libc
::SOCK_STREAM
)?
;
325 Ok((UnixStream(i1
), UnixStream(i2
)))
328 /// Creates a new independently owned handle to the underlying socket.
330 /// The returned `UnixStream` is a reference to the same stream that this
331 /// object references. Both handles will read and write the same stream of
332 /// data, and options set on one stream will be propagated to the other
338 /// use std::os::unix::net::UnixStream;
340 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
341 /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
343 #[stable(feature = "unix_socket", since = "1.10.0")]
344 pub fn try_clone(&self) -> io
::Result
<UnixStream
> {
345 self.0.duplicate().map(UnixStream
)
348 /// Returns the socket address of the local half of this connection.
353 /// use std::os::unix::net::UnixStream;
355 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
356 /// let addr = socket.local_addr().expect("Couldn't get local address");
358 #[stable(feature = "unix_socket", since = "1.10.0")]
359 pub fn local_addr(&self) -> io
::Result
<SocketAddr
> {
360 SocketAddr
::new(|addr
, len
| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }
)
363 /// Returns the socket address of the remote half of this connection.
368 /// use std::os::unix::net::UnixStream;
370 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
371 /// let addr = socket.peer_addr().expect("Couldn't get peer address");
373 #[stable(feature = "unix_socket", since = "1.10.0")]
374 pub fn peer_addr(&self) -> io
::Result
<SocketAddr
> {
375 SocketAddr
::new(|addr
, len
| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) }
)
378 /// Sets the read timeout for the socket.
380 /// If the provided value is [`None`], then [`read`] calls will block
381 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
384 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
385 /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
386 /// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read
387 /// [`Duration`]: ../../../../std/time/struct.Duration.html
392 /// use std::os::unix::net::UnixStream;
393 /// use std::time::Duration;
395 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
396 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
399 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
404 /// use std::os::unix::net::UnixStream;
405 /// use std::time::Duration;
407 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
408 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
409 /// let err = result.unwrap_err();
410 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
412 #[stable(feature = "unix_socket", since = "1.10.0")]
413 pub fn set_read_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
414 self.0.set_timeout(timeout
, libc
::SO_RCVTIMEO
)
417 /// Sets the write timeout for the socket.
419 /// If the provided value is [`None`], then [`write`] calls will block
420 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
421 /// passed to this method.
423 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
424 /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
425 /// [`write`]: ../../../../std/io/trait.Write.html#tymethod.write
426 /// [`Duration`]: ../../../../std/time/struct.Duration.html
431 /// use std::os::unix::net::UnixStream;
432 /// use std::time::Duration;
434 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
435 /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
438 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
443 /// use std::net::UdpSocket;
444 /// use std::time::Duration;
446 /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
447 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
448 /// let err = result.unwrap_err();
449 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
451 #[stable(feature = "unix_socket", since = "1.10.0")]
452 pub fn set_write_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
453 self.0.set_timeout(timeout
, libc
::SO_SNDTIMEO
)
456 /// Returns the read timeout of this socket.
461 /// use std::os::unix::net::UnixStream;
462 /// use std::time::Duration;
464 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
465 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
466 /// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0)));
468 #[stable(feature = "unix_socket", since = "1.10.0")]
469 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
470 self.0.timeout(libc
::SO_RCVTIMEO
)
473 /// Returns the write timeout of this socket.
478 /// use std::os::unix::net::UnixStream;
479 /// use std::time::Duration;
481 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
482 /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
483 /// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0)));
485 #[stable(feature = "unix_socket", since = "1.10.0")]
486 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
487 self.0.timeout(libc
::SO_SNDTIMEO
)
490 /// Moves the socket into or out of nonblocking mode.
495 /// use std::os::unix::net::UnixStream;
497 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
498 /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
500 #[stable(feature = "unix_socket", since = "1.10.0")]
501 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
502 self.0.set_nonblocking(nonblocking
)
505 /// Returns the value of the `SO_ERROR` option.
510 /// use std::os::unix::net::UnixStream;
512 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
513 /// if let Ok(Some(err)) = socket.take_error() {
514 /// println!("Got error: {:?}", err);
518 /// # Platform specific
519 /// On Redox this always returns `None`.
520 #[stable(feature = "unix_socket", since = "1.10.0")]
521 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
525 /// Shuts down the read, write, or both halves of this connection.
527 /// This function will cause all pending and future I/O calls on the
528 /// specified portions to immediately return with an appropriate value
529 /// (see the documentation of [`Shutdown`]).
531 /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
536 /// use std::os::unix::net::UnixStream;
537 /// use std::net::Shutdown;
539 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
540 /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
542 #[stable(feature = "unix_socket", since = "1.10.0")]
543 pub fn shutdown(&self, how
: Shutdown
) -> io
::Result
<()> {
548 #[stable(feature = "unix_socket", since = "1.10.0")]
549 impl io
::Read
for UnixStream
{
550 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
551 io
::Read
::read(&mut &*self, buf
)
554 fn read_vectored(&mut self, bufs
: &mut [IoVecMut
<'_
>]) -> io
::Result
<usize> {
555 io
::Read
::read_vectored(&mut &*self, bufs
)
559 unsafe fn initializer(&self) -> Initializer
{
564 #[stable(feature = "unix_socket", since = "1.10.0")]
565 impl<'a
> io
::Read
for &'a UnixStream
{
566 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
570 fn read_vectored(&mut self, bufs
: &mut [IoVecMut
<'_
>]) -> io
::Result
<usize> {
571 self.0.read_vectored(bufs
)
575 unsafe fn initializer(&self) -> Initializer
{
580 #[stable(feature = "unix_socket", since = "1.10.0")]
581 impl io
::Write
for UnixStream
{
582 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
583 io
::Write
::write(&mut &*self, buf
)
586 fn write_vectored(&mut self, bufs
: &[IoVec
<'_
>]) -> io
::Result
<usize> {
587 io
::Write
::write_vectored(&mut &*self, bufs
)
590 fn flush(&mut self) -> io
::Result
<()> {
591 io
::Write
::flush(&mut &*self)
595 #[stable(feature = "unix_socket", since = "1.10.0")]
596 impl<'a
> io
::Write
for &'a UnixStream
{
597 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
601 fn write_vectored(&mut self, bufs
: &[IoVec
<'_
>]) -> io
::Result
<usize> {
602 self.0.write_vectored(bufs
)
605 fn flush(&mut self) -> io
::Result
<()> {
610 #[stable(feature = "unix_socket", since = "1.10.0")]
611 impl AsRawFd
for UnixStream
{
612 fn as_raw_fd(&self) -> RawFd
{
617 #[stable(feature = "unix_socket", since = "1.10.0")]
618 impl FromRawFd
for UnixStream
{
619 unsafe fn from_raw_fd(fd
: RawFd
) -> UnixStream
{
620 UnixStream(Socket
::from_inner(fd
))
624 #[stable(feature = "unix_socket", since = "1.10.0")]
625 impl IntoRawFd
for UnixStream
{
626 fn into_raw_fd(self) -> RawFd
{
631 #[stable(feature = "rust1", since = "1.0.0")]
632 impl AsRawFd
for net
::TcpStream
{
633 fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
636 #[stable(feature = "rust1", since = "1.0.0")]
637 impl AsRawFd
for net
::TcpListener
{
638 fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
641 #[stable(feature = "rust1", since = "1.0.0")]
642 impl AsRawFd
for net
::UdpSocket
{
643 fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
646 #[stable(feature = "from_raw_os", since = "1.1.0")]
647 impl FromRawFd
for net
::TcpStream
{
648 unsafe fn from_raw_fd(fd
: RawFd
) -> net
::TcpStream
{
649 let socket
= sys
::net
::Socket
::from_inner(fd
);
650 net
::TcpStream
::from_inner(sys_common
::net
::TcpStream
::from_inner(socket
))
654 #[stable(feature = "from_raw_os", since = "1.1.0")]
655 impl FromRawFd
for net
::TcpListener
{
656 unsafe fn from_raw_fd(fd
: RawFd
) -> net
::TcpListener
{
657 let socket
= sys
::net
::Socket
::from_inner(fd
);
658 net
::TcpListener
::from_inner(sys_common
::net
::TcpListener
::from_inner(socket
))
662 #[stable(feature = "from_raw_os", since = "1.1.0")]
663 impl FromRawFd
for net
::UdpSocket
{
664 unsafe fn from_raw_fd(fd
: RawFd
) -> net
::UdpSocket
{
665 let socket
= sys
::net
::Socket
::from_inner(fd
);
666 net
::UdpSocket
::from_inner(sys_common
::net
::UdpSocket
::from_inner(socket
))
670 #[stable(feature = "into_raw_os", since = "1.4.0")]
671 impl IntoRawFd
for net
::TcpStream
{
672 fn into_raw_fd(self) -> RawFd
{
673 self.into_inner().into_socket().into_inner()
676 #[stable(feature = "into_raw_os", since = "1.4.0")]
677 impl IntoRawFd
for net
::TcpListener
{
678 fn into_raw_fd(self) -> RawFd
{
679 self.into_inner().into_socket().into_inner()
682 #[stable(feature = "into_raw_os", since = "1.4.0")]
683 impl IntoRawFd
for net
::UdpSocket
{
684 fn into_raw_fd(self) -> RawFd
{
685 self.into_inner().into_socket().into_inner()
689 /// A structure representing a Unix domain socket server.
695 /// use std::os::unix::net::{UnixStream, UnixListener};
697 /// fn handle_client(stream: UnixStream) {
701 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
703 /// // accept connections and process them, spawning a new thread for each one
704 /// for stream in listener.incoming() {
707 /// /* connection succeeded */
708 /// thread::spawn(|| handle_client(stream));
711 /// /* connection failed */
717 #[stable(feature = "unix_socket", since = "1.10.0")]
718 pub struct UnixListener(Socket
);
720 #[stable(feature = "unix_socket", since = "1.10.0")]
721 impl fmt
::Debug
for UnixListener
{
722 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
723 let mut builder
= fmt
.debug_struct("UnixListener");
724 builder
.field("fd", self.0.as_inner());
725 if let Ok(addr
) = self.local_addr() {
726 builder
.field("local", &addr
);
733 /// Creates a new `UnixListener` bound to the specified socket.
738 /// use std::os::unix::net::UnixListener;
740 /// let listener = match UnixListener::bind("/path/to/the/socket") {
741 /// Ok(sock) => sock,
743 /// println!("Couldn't connect: {:?}", e);
748 #[stable(feature = "unix_socket", since = "1.10.0")]
749 pub fn bind
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<UnixListener
> {
750 fn inner(path
: &Path
) -> io
::Result
<UnixListener
> {
752 let inner
= Socket
::new_raw(libc
::AF_UNIX
, libc
::SOCK_STREAM
)?
;
753 let (addr
, len
) = sockaddr_un(path
)?
;
755 cvt(libc
::bind(*inner
.as_inner(), &addr
as *const _
as *const _
, len
as _
))?
;
756 cvt(libc
::listen(*inner
.as_inner(), 128))?
;
758 Ok(UnixListener(inner
))
764 /// Accepts a new incoming connection to this listener.
766 /// This function will block the calling thread until a new Unix connection
767 /// is established. When established, the corresponding [`UnixStream`] and
768 /// the remote peer's address will be returned.
770 /// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html
775 /// use std::os::unix::net::UnixListener;
777 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
779 /// match listener.accept() {
780 /// Ok((socket, addr)) => println!("Got a client: {:?}", addr),
781 /// Err(e) => println!("accept function failed: {:?}", e),
784 #[stable(feature = "unix_socket", since = "1.10.0")]
785 pub fn accept(&self) -> io
::Result
<(UnixStream
, SocketAddr
)> {
786 let mut storage
: libc
::sockaddr_un
= unsafe { mem::zeroed() }
;
787 let mut len
= mem
::size_of_val(&storage
) as libc
::socklen_t
;
788 let sock
= self.0.accept(&mut storage
as *mut _
as *mut _
, &mut len
)?
;
789 let addr
= SocketAddr
::from_parts(storage
, len
)?
;
790 Ok((UnixStream(sock
), addr
))
793 /// Creates a new independently owned handle to the underlying socket.
795 /// The returned `UnixListener` is a reference to the same socket that this
796 /// object references. Both handles can be used to accept incoming
797 /// connections and options set on one listener will affect the other.
802 /// use std::os::unix::net::UnixListener;
804 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
806 /// let listener_copy = listener.try_clone().expect("try_clone failed");
808 #[stable(feature = "unix_socket", since = "1.10.0")]
809 pub fn try_clone(&self) -> io
::Result
<UnixListener
> {
810 self.0.duplicate().map(UnixListener
)
813 /// Returns the local socket address of this listener.
818 /// use std::os::unix::net::UnixListener;
820 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
822 /// let addr = listener.local_addr().expect("Couldn't get local address");
824 #[stable(feature = "unix_socket", since = "1.10.0")]
825 pub fn local_addr(&self) -> io
::Result
<SocketAddr
> {
826 SocketAddr
::new(|addr
, len
| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }
)
829 /// Moves the socket into or out of nonblocking mode.
834 /// use std::os::unix::net::UnixListener;
836 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
838 /// listener.set_nonblocking(true).expect("Couldn't set non blocking");
840 #[stable(feature = "unix_socket", since = "1.10.0")]
841 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
842 self.0.set_nonblocking(nonblocking
)
845 /// Returns the value of the `SO_ERROR` option.
850 /// use std::os::unix::net::UnixListener;
852 /// let listener = UnixListener::bind("/tmp/sock").unwrap();
854 /// if let Ok(Some(err)) = listener.take_error() {
855 /// println!("Got error: {:?}", err);
859 /// # Platform specific
860 /// On Redox this always returns `None`.
861 #[stable(feature = "unix_socket", since = "1.10.0")]
862 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
866 /// Returns an iterator over incoming connections.
868 /// The iterator will never return [`None`] and will also not yield the
869 /// peer's [`SocketAddr`] structure.
871 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
872 /// [`SocketAddr`]: struct.SocketAddr.html
878 /// use std::os::unix::net::{UnixStream, UnixListener};
880 /// fn handle_client(stream: UnixStream) {
884 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
886 /// for stream in listener.incoming() {
889 /// thread::spawn(|| handle_client(stream));
897 #[stable(feature = "unix_socket", since = "1.10.0")]
898 pub fn incoming
<'a
>(&'a
self) -> Incoming
<'a
> {
899 Incoming { listener: self }
903 #[stable(feature = "unix_socket", since = "1.10.0")]
904 impl AsRawFd
for UnixListener
{
905 fn as_raw_fd(&self) -> RawFd
{
910 #[stable(feature = "unix_socket", since = "1.10.0")]
911 impl FromRawFd
for UnixListener
{
912 unsafe fn from_raw_fd(fd
: RawFd
) -> UnixListener
{
913 UnixListener(Socket
::from_inner(fd
))
917 #[stable(feature = "unix_socket", since = "1.10.0")]
918 impl IntoRawFd
for UnixListener
{
919 fn into_raw_fd(self) -> RawFd
{
924 #[stable(feature = "unix_socket", since = "1.10.0")]
925 impl<'a
> IntoIterator
for &'a UnixListener
{
926 type Item
= io
::Result
<UnixStream
>;
927 type IntoIter
= Incoming
<'a
>;
929 fn into_iter(self) -> Incoming
<'a
> {
934 /// An iterator over incoming connections to a [`UnixListener`].
936 /// It will never return [`None`].
938 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
939 /// [`UnixListener`]: struct.UnixListener.html
945 /// use std::os::unix::net::{UnixStream, UnixListener};
947 /// fn handle_client(stream: UnixStream) {
951 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
953 /// for stream in listener.incoming() {
956 /// thread::spawn(|| handle_client(stream));
965 #[stable(feature = "unix_socket", since = "1.10.0")]
966 pub struct Incoming
<'a
> {
967 listener
: &'a UnixListener
,
970 #[stable(feature = "unix_socket", since = "1.10.0")]
971 impl<'a
> Iterator
for Incoming
<'a
> {
972 type Item
= io
::Result
<UnixStream
>;
974 fn next(&mut self) -> Option
<io
::Result
<UnixStream
>> {
975 Some(self.listener
.accept().map(|s
| s
.0))
978 fn size_hint(&self) -> (usize, Option
<usize>) {
979 (usize::max_value(), None
)
983 /// A Unix datagram socket.
988 /// use std::os::unix::net::UnixDatagram;
990 /// let socket = UnixDatagram::bind("/path/to/my/socket").unwrap();
991 /// socket.send_to(b"hello world", "/path/to/other/socket").unwrap();
992 /// let mut buf = [0; 100];
993 /// let (count, address) = socket.recv_from(&mut buf).unwrap();
994 /// println!("socket {:?} sent {:?}", address, &buf[..count]);
996 #[stable(feature = "unix_socket", since = "1.10.0")]
997 pub struct UnixDatagram(Socket
);
999 #[stable(feature = "unix_socket", since = "1.10.0")]
1000 impl fmt
::Debug
for UnixDatagram
{
1001 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
1002 let mut builder
= fmt
.debug_struct("UnixDatagram");
1003 builder
.field("fd", self.0.as_inner());
1004 if let Ok(addr
) = self.local_addr() {
1005 builder
.field("local", &addr
);
1007 if let Ok(addr
) = self.peer_addr() {
1008 builder
.field("peer", &addr
);
1015 /// Creates a Unix datagram socket bound to the given path.
1020 /// use std::os::unix::net::UnixDatagram;
1022 /// let sock = match UnixDatagram::bind("/path/to/the/socket") {
1023 /// Ok(sock) => sock,
1025 /// println!("Couldn't bind: {:?}", e);
1030 #[stable(feature = "unix_socket", since = "1.10.0")]
1031 pub fn bind
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<UnixDatagram
> {
1032 fn inner(path
: &Path
) -> io
::Result
<UnixDatagram
> {
1034 let socket
= UnixDatagram
::unbound()?
;
1035 let (addr
, len
) = sockaddr_un(path
)?
;
1037 cvt(libc
::bind(*socket
.0.as_inner(), &addr
as *const _
as *const _
, len
as _
))?
;
1042 inner(path
.as_ref())
1045 /// Creates a Unix Datagram socket which is not bound to any address.
1050 /// use std::os::unix::net::UnixDatagram;
1052 /// let sock = match UnixDatagram::unbound() {
1053 /// Ok(sock) => sock,
1055 /// println!("Couldn't unbound: {:?}", e);
1060 #[stable(feature = "unix_socket", since = "1.10.0")]
1061 pub fn unbound() -> io
::Result
<UnixDatagram
> {
1062 let inner
= Socket
::new_raw(libc
::AF_UNIX
, libc
::SOCK_DGRAM
)?
;
1063 Ok(UnixDatagram(inner
))
1066 /// Creates an unnamed pair of connected sockets.
1068 /// Returns two `UnixDatagrams`s which are connected to each other.
1073 /// use std::os::unix::net::UnixDatagram;
1075 /// let (sock1, sock2) = match UnixDatagram::pair() {
1076 /// Ok((sock1, sock2)) => (sock1, sock2),
1078 /// println!("Couldn't unbound: {:?}", e);
1083 #[stable(feature = "unix_socket", since = "1.10.0")]
1084 pub fn pair() -> io
::Result
<(UnixDatagram
, UnixDatagram
)> {
1085 let (i1
, i2
) = Socket
::new_pair(libc
::AF_UNIX
, libc
::SOCK_DGRAM
)?
;
1086 Ok((UnixDatagram(i1
), UnixDatagram(i2
)))
1089 /// Connects the socket to the specified address.
1091 /// The [`send`] method may be used to send data to the specified address.
1092 /// [`recv`] and [`recv_from`] will only receive data from that address.
1094 /// [`send`]: #method.send
1095 /// [`recv`]: #method.recv
1096 /// [`recv_from`]: #method.recv_from
1101 /// use std::os::unix::net::UnixDatagram;
1103 /// let sock = UnixDatagram::unbound().unwrap();
1104 /// match sock.connect("/path/to/the/socket") {
1105 /// Ok(sock) => sock,
1107 /// println!("Couldn't connect: {:?}", e);
1112 #[stable(feature = "unix_socket", since = "1.10.0")]
1113 pub fn connect
<P
: AsRef
<Path
>>(&self, path
: P
) -> io
::Result
<()> {
1114 fn inner(d
: &UnixDatagram
, path
: &Path
) -> io
::Result
<()> {
1116 let (addr
, len
) = sockaddr_un(path
)?
;
1118 cvt(libc
::connect(*d
.0.as_inner(), &addr
as *const _
as *const _
, len
))?
;
1123 inner(self, path
.as_ref())
1126 /// Creates a new independently owned handle to the underlying socket.
1128 /// The returned `UnixDatagram` is a reference to the same socket that this
1129 /// object references. Both handles can be used to accept incoming
1130 /// connections and options set on one side will affect the other.
1135 /// use std::os::unix::net::UnixDatagram;
1137 /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
1139 /// let sock_copy = sock.try_clone().expect("try_clone failed");
1141 #[stable(feature = "unix_socket", since = "1.10.0")]
1142 pub fn try_clone(&self) -> io
::Result
<UnixDatagram
> {
1143 self.0.duplicate().map(UnixDatagram
)
1146 /// Returns the address of this socket.
1151 /// use std::os::unix::net::UnixDatagram;
1153 /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
1155 /// let addr = sock.local_addr().expect("Couldn't get local address");
1157 #[stable(feature = "unix_socket", since = "1.10.0")]
1158 pub fn local_addr(&self) -> io
::Result
<SocketAddr
> {
1159 SocketAddr
::new(|addr
, len
| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }
)
1162 /// Returns the address of this socket's peer.
1164 /// The [`connect`] method will connect the socket to a peer.
1166 /// [`connect`]: #method.connect
1171 /// use std::os::unix::net::UnixDatagram;
1173 /// let sock = UnixDatagram::unbound().unwrap();
1174 /// sock.connect("/path/to/the/socket").unwrap();
1176 /// let addr = sock.peer_addr().expect("Couldn't get peer address");
1178 #[stable(feature = "unix_socket", since = "1.10.0")]
1179 pub fn peer_addr(&self) -> io
::Result
<SocketAddr
> {
1180 SocketAddr
::new(|addr
, len
| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) }
)
1183 /// Receives data from the socket.
1185 /// On success, returns the number of bytes read and the address from
1186 /// whence the data came.
1191 /// use std::os::unix::net::UnixDatagram;
1193 /// let sock = UnixDatagram::unbound().unwrap();
1194 /// let mut buf = vec![0; 10];
1195 /// match sock.recv_from(buf.as_mut_slice()) {
1196 /// Ok((size, sender)) => println!("received {} bytes from {:?}", size, sender),
1197 /// Err(e) => println!("recv_from function failed: {:?}", e),
1200 #[stable(feature = "unix_socket", since = "1.10.0")]
1201 pub fn recv_from(&self, buf
: &mut [u8]) -> io
::Result
<(usize, SocketAddr
)> {
1203 let addr
= SocketAddr
::new(|addr
, len
| {
1205 count
= libc
::recvfrom(*self.0.as_inner(),
1206 buf
.as_mut_ptr() as *mut _
,
1213 } else if count
== 0 {
1221 Ok((count
as usize, addr
))
1224 /// Receives data from the socket.
1226 /// On success, returns the number of bytes read.
1231 /// use std::os::unix::net::UnixDatagram;
1233 /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
1234 /// let mut buf = vec![0; 10];
1235 /// sock.recv(buf.as_mut_slice()).expect("recv function failed");
1237 #[stable(feature = "unix_socket", since = "1.10.0")]
1238 pub fn recv(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
1242 /// Sends data on the socket to the specified address.
1244 /// On success, returns the number of bytes written.
1249 /// use std::os::unix::net::UnixDatagram;
1251 /// let sock = UnixDatagram::unbound().unwrap();
1252 /// sock.send_to(b"omelette au fromage", "/some/sock").expect("send_to function failed");
1254 #[stable(feature = "unix_socket", since = "1.10.0")]
1255 pub fn send_to
<P
: AsRef
<Path
>>(&self, buf
: &[u8], path
: P
) -> io
::Result
<usize> {
1256 fn inner(d
: &UnixDatagram
, buf
: &[u8], path
: &Path
) -> io
::Result
<usize> {
1258 let (addr
, len
) = sockaddr_un(path
)?
;
1260 let count
= cvt(libc
::sendto(*d
.0.as_inner(),
1261 buf
.as_ptr() as *const _
,
1264 &addr
as *const _
as *const _
,
1269 inner(self, buf
, path
.as_ref())
1272 /// Sends data on the socket to the socket's peer.
1274 /// The peer address may be set by the `connect` method, and this method
1275 /// will return an error if the socket has not already been connected.
1277 /// On success, returns the number of bytes written.
1282 /// use std::os::unix::net::UnixDatagram;
1284 /// let sock = UnixDatagram::unbound().unwrap();
1285 /// sock.connect("/some/sock").expect("Couldn't connect");
1286 /// sock.send(b"omelette au fromage").expect("send_to function failed");
1288 #[stable(feature = "unix_socket", since = "1.10.0")]
1289 pub fn send(&self, buf
: &[u8]) -> io
::Result
<usize> {
1293 /// Sets the read timeout for the socket.
1295 /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will
1296 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`]
1297 /// is passed to this method.
1299 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
1300 /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
1301 /// [`recv`]: #method.recv
1302 /// [`recv_from`]: #method.recv_from
1303 /// [`Duration`]: ../../../../std/time/struct.Duration.html
1308 /// use std::os::unix::net::UnixDatagram;
1309 /// use std::time::Duration;
1311 /// let sock = UnixDatagram::unbound().unwrap();
1312 /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed");
1315 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
1320 /// use std::os::unix::net::UnixDatagram;
1321 /// use std::time::Duration;
1323 /// let socket = UnixDatagram::unbound().unwrap();
1324 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
1325 /// let err = result.unwrap_err();
1326 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
1328 #[stable(feature = "unix_socket", since = "1.10.0")]
1329 pub fn set_read_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
1330 self.0.set_timeout(timeout
, libc
::SO_RCVTIMEO
)
1333 /// Sets the write timeout for the socket.
1335 /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will
1336 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
1339 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
1340 /// [`send`]: #method.send
1341 /// [`send_to`]: #method.send_to
1342 /// [`Duration`]: ../../../../std/time/struct.Duration.html
1347 /// use std::os::unix::net::UnixDatagram;
1348 /// use std::time::Duration;
1350 /// let sock = UnixDatagram::unbound().unwrap();
1351 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
1352 /// .expect("set_write_timeout function failed");
1355 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
1360 /// use std::os::unix::net::UnixDatagram;
1361 /// use std::time::Duration;
1363 /// let socket = UnixDatagram::unbound().unwrap();
1364 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
1365 /// let err = result.unwrap_err();
1366 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
1368 #[stable(feature = "unix_socket", since = "1.10.0")]
1369 pub fn set_write_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
1370 self.0.set_timeout(timeout
, libc
::SO_SNDTIMEO
)
1373 /// Returns the read timeout of this socket.
1378 /// use std::os::unix::net::UnixDatagram;
1379 /// use std::time::Duration;
1381 /// let sock = UnixDatagram::unbound().unwrap();
1382 /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed");
1383 /// assert_eq!(sock.read_timeout().unwrap(), Some(Duration::new(1, 0)));
1385 #[stable(feature = "unix_socket", since = "1.10.0")]
1386 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
1387 self.0.timeout(libc
::SO_RCVTIMEO
)
1390 /// Returns the write timeout of this socket.
1395 /// use std::os::unix::net::UnixDatagram;
1396 /// use std::time::Duration;
1398 /// let sock = UnixDatagram::unbound().unwrap();
1399 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
1400 /// .expect("set_write_timeout function failed");
1401 /// assert_eq!(sock.write_timeout().unwrap(), Some(Duration::new(1, 0)));
1403 #[stable(feature = "unix_socket", since = "1.10.0")]
1404 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
1405 self.0.timeout(libc
::SO_SNDTIMEO
)
1408 /// Moves the socket into or out of nonblocking mode.
1413 /// use std::os::unix::net::UnixDatagram;
1415 /// let sock = UnixDatagram::unbound().unwrap();
1416 /// sock.set_nonblocking(true).expect("set_nonblocking function failed");
1418 #[stable(feature = "unix_socket", since = "1.10.0")]
1419 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
1420 self.0.set_nonblocking(nonblocking
)
1423 /// Returns the value of the `SO_ERROR` option.
1428 /// use std::os::unix::net::UnixDatagram;
1430 /// let sock = UnixDatagram::unbound().unwrap();
1431 /// if let Ok(Some(err)) = sock.take_error() {
1432 /// println!("Got error: {:?}", err);
1435 #[stable(feature = "unix_socket", since = "1.10.0")]
1436 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
1440 /// Shut down the read, write, or both halves of this connection.
1442 /// This function will cause all pending and future I/O calls on the
1443 /// specified portions to immediately return with an appropriate value
1444 /// (see the documentation of [`Shutdown`]).
1446 /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
1449 /// use std::os::unix::net::UnixDatagram;
1450 /// use std::net::Shutdown;
1452 /// let sock = UnixDatagram::unbound().unwrap();
1453 /// sock.shutdown(Shutdown::Both).expect("shutdown function failed");
1455 #[stable(feature = "unix_socket", since = "1.10.0")]
1456 pub fn shutdown(&self, how
: Shutdown
) -> io
::Result
<()> {
1457 self.0.shutdown(how
)
1461 #[stable(feature = "unix_socket", since = "1.10.0")]
1462 impl AsRawFd
for UnixDatagram
{
1463 fn as_raw_fd(&self) -> RawFd
{
1468 #[stable(feature = "unix_socket", since = "1.10.0")]
1469 impl FromRawFd
for UnixDatagram
{
1470 unsafe fn from_raw_fd(fd
: RawFd
) -> UnixDatagram
{
1471 UnixDatagram(Socket
::from_inner(fd
))
1475 #[stable(feature = "unix_socket", since = "1.10.0")]
1476 impl IntoRawFd
for UnixDatagram
{
1477 fn into_raw_fd(self) -> RawFd
{
1482 #[cfg(all(test, not(target_os = "emscripten")))]
1485 use io
::{self, ErrorKind}
;
1488 use sys_common
::io
::test
::tmpdir
;
1492 macro_rules
! or_panic
{
1496 Err(e
) => panic
!("{}", e
),
1504 let socket_path
= dir
.path().join("sock");
1505 let msg1
= b
"hello";
1506 let msg2
= b
"world!";
1508 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1509 let thread
= thread
::spawn(move || {
1510 let mut stream
= or_panic
!(listener
.accept()).0;
1511 let mut buf
= [0; 5];
1512 or_panic
!(stream
.read(&mut buf
));
1513 assert_eq
!(&msg1
[..], &buf
[..]);
1514 or_panic
!(stream
.write_all(msg2
));
1517 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1518 assert_eq
!(Some(&*socket_path
),
1519 stream
.peer_addr().unwrap().as_pathname());
1520 or_panic
!(stream
.write_all(msg1
));
1521 let mut buf
= vec
![];
1522 or_panic
!(stream
.read_to_end(&mut buf
));
1523 assert_eq
!(&msg2
[..], &buf
[..]);
1526 thread
.join().unwrap();
1531 let (mut s1
, mut s2
) = or_panic
!(UnixStream
::pair());
1533 let len
= or_panic
!(s1
.write_vectored(
1534 &[IoVec
::new(b
"hello"), IoVec
::new(b
" "), IoVec
::new(b
"world!")],
1536 assert_eq
!(len
, 12);
1538 let mut buf1
= [0; 6];
1539 let mut buf2
= [0; 7];
1540 let len
= or_panic
!(s2
.read_vectored(
1541 &mut [IoVecMut
::new(&mut buf1
), IoVecMut
::new(&mut buf2
)],
1543 assert_eq
!(len
, 12);
1544 assert_eq
!(&buf1
, b
"hello ");
1545 assert_eq
!(&buf2
, b
"world!\0");
1550 let msg1
= b
"hello";
1551 let msg2
= b
"world!";
1553 let (mut s1
, mut s2
) = or_panic
!(UnixStream
::pair());
1554 let thread
= thread
::spawn(move || {
1555 // s1 must be moved in or the test will hang!
1556 let mut buf
= [0; 5];
1557 or_panic
!(s1
.read(&mut buf
));
1558 assert_eq
!(&msg1
[..], &buf
[..]);
1559 or_panic
!(s1
.write_all(msg2
));
1562 or_panic
!(s2
.write_all(msg1
));
1563 let mut buf
= vec
![];
1564 or_panic
!(s2
.read_to_end(&mut buf
));
1565 assert_eq
!(&msg2
[..], &buf
[..]);
1568 thread
.join().unwrap();
1574 let socket_path
= dir
.path().join("sock");
1575 let msg1
= b
"hello";
1576 let msg2
= b
"world";
1578 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1579 let thread
= thread
::spawn(move || {
1580 let mut stream
= or_panic
!(listener
.accept()).0;
1581 or_panic
!(stream
.write_all(msg1
));
1582 or_panic
!(stream
.write_all(msg2
));
1585 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1586 let mut stream2
= or_panic
!(stream
.try_clone());
1588 let mut buf
= [0; 5];
1589 or_panic
!(stream
.read(&mut buf
));
1590 assert_eq
!(&msg1
[..], &buf
[..]);
1591 or_panic
!(stream2
.read(&mut buf
));
1592 assert_eq
!(&msg2
[..], &buf
[..]);
1594 thread
.join().unwrap();
1600 let socket_path
= dir
.path().join("sock");
1602 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1603 let thread
= thread
::spawn(move || {
1604 for stream
in listener
.incoming().take(2) {
1605 let mut stream
= or_panic
!(stream
);
1607 or_panic
!(stream
.read(&mut buf
));
1612 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1613 or_panic
!(stream
.write_all(&[0]));
1616 thread
.join().unwrap();
1622 let socket_path
= dir
.path()
1623 .join("asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\
1624 sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf");
1625 match UnixStream
::connect(&socket_path
) {
1626 Err(ref e
) if e
.kind() == io
::ErrorKind
::InvalidInput
=> {}
1627 Err(e
) => panic
!("unexpected error {}", e
),
1628 Ok(_
) => panic
!("unexpected success"),
1631 match UnixListener
::bind(&socket_path
) {
1632 Err(ref e
) if e
.kind() == io
::ErrorKind
::InvalidInput
=> {}
1633 Err(e
) => panic
!("unexpected error {}", e
),
1634 Ok(_
) => panic
!("unexpected success"),
1637 match UnixDatagram
::bind(&socket_path
) {
1638 Err(ref e
) if e
.kind() == io
::ErrorKind
::InvalidInput
=> {}
1639 Err(e
) => panic
!("unexpected error {}", e
),
1640 Ok(_
) => panic
!("unexpected success"),
1647 let socket_path
= dir
.path().join("sock");
1649 let _listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1651 let stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1652 let dur
= Duration
::new(15410, 0);
1654 assert_eq
!(None
, or_panic
!(stream
.read_timeout()));
1656 or_panic
!(stream
.set_read_timeout(Some(dur
)));
1657 assert_eq
!(Some(dur
), or_panic
!(stream
.read_timeout()));
1659 assert_eq
!(None
, or_panic
!(stream
.write_timeout()));
1661 or_panic
!(stream
.set_write_timeout(Some(dur
)));
1662 assert_eq
!(Some(dur
), or_panic
!(stream
.write_timeout()));
1664 or_panic
!(stream
.set_read_timeout(None
));
1665 assert_eq
!(None
, or_panic
!(stream
.read_timeout()));
1667 or_panic
!(stream
.set_write_timeout(None
));
1668 assert_eq
!(None
, or_panic
!(stream
.write_timeout()));
1672 fn test_read_timeout() {
1674 let socket_path
= dir
.path().join("sock");
1676 let _listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1678 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1679 or_panic
!(stream
.set_read_timeout(Some(Duration
::from_millis(1000))));
1681 let mut buf
= [0; 10];
1682 let kind
= stream
.read_exact(&mut buf
).err().expect("expected error").kind();
1683 assert
!(kind
== ErrorKind
::WouldBlock
|| kind
== ErrorKind
::TimedOut
,
1684 "unexpected_error: {:?}", kind
);
1688 fn test_read_with_timeout() {
1690 let socket_path
= dir
.path().join("sock");
1692 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1694 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1695 or_panic
!(stream
.set_read_timeout(Some(Duration
::from_millis(1000))));
1697 let mut other_end
= or_panic
!(listener
.accept()).0;
1698 or_panic
!(other_end
.write_all(b
"hello world"));
1700 let mut buf
= [0; 11];
1701 or_panic
!(stream
.read(&mut buf
));
1702 assert_eq
!(b
"hello world", &buf
[..]);
1704 let kind
= stream
.read_exact(&mut buf
).err().expect("expected error").kind();
1705 assert
!(kind
== ErrorKind
::WouldBlock
|| kind
== ErrorKind
::TimedOut
,
1706 "unexpected_error: {:?}", kind
);
1709 // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
1710 // when passed zero Durations
1712 fn test_unix_stream_timeout_zero_duration() {
1714 let socket_path
= dir
.path().join("sock");
1716 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
1717 let stream
= or_panic
!(UnixStream
::connect(&socket_path
));
1719 let result
= stream
.set_write_timeout(Some(Duration
::new(0, 0)));
1720 let err
= result
.unwrap_err();
1721 assert_eq
!(err
.kind(), ErrorKind
::InvalidInput
);
1723 let result
= stream
.set_read_timeout(Some(Duration
::new(0, 0)));
1724 let err
= result
.unwrap_err();
1725 assert_eq
!(err
.kind(), ErrorKind
::InvalidInput
);
1731 fn test_unix_datagram() {
1733 let path1
= dir
.path().join("sock1");
1734 let path2
= dir
.path().join("sock2");
1736 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
1737 let sock2
= or_panic
!(UnixDatagram
::bind(&path2
));
1739 let msg
= b
"hello world";
1740 or_panic
!(sock1
.send_to(msg
, &path2
));
1741 let mut buf
= [0; 11];
1742 or_panic
!(sock2
.recv_from(&mut buf
));
1743 assert_eq
!(msg
, &buf
[..]);
1747 fn test_unnamed_unix_datagram() {
1749 let path1
= dir
.path().join("sock1");
1751 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
1752 let sock2
= or_panic
!(UnixDatagram
::unbound());
1754 let msg
= b
"hello world";
1755 or_panic
!(sock2
.send_to(msg
, &path1
));
1756 let mut buf
= [0; 11];
1757 let (usize, addr
) = or_panic
!(sock1
.recv_from(&mut buf
));
1758 assert_eq
!(usize, 11);
1759 assert
!(addr
.is_unnamed());
1760 assert_eq
!(msg
, &buf
[..]);
1764 fn test_connect_unix_datagram() {
1766 let path1
= dir
.path().join("sock1");
1767 let path2
= dir
.path().join("sock2");
1769 let bsock1
= or_panic
!(UnixDatagram
::bind(&path1
));
1770 let bsock2
= or_panic
!(UnixDatagram
::bind(&path2
));
1771 let sock
= or_panic
!(UnixDatagram
::unbound());
1772 or_panic
!(sock
.connect(&path1
));
1775 let msg
= b
"hello there";
1776 or_panic
!(sock
.send(msg
));
1777 let mut buf
= [0; 11];
1778 let (usize, addr
) = or_panic
!(bsock1
.recv_from(&mut buf
));
1779 assert_eq
!(usize, 11);
1780 assert
!(addr
.is_unnamed());
1781 assert_eq
!(msg
, &buf
[..]);
1783 // Changing default socket works too
1784 or_panic
!(sock
.connect(&path2
));
1785 or_panic
!(sock
.send(msg
));
1786 or_panic
!(bsock2
.recv_from(&mut buf
));
1790 fn test_unix_datagram_recv() {
1792 let path1
= dir
.path().join("sock1");
1794 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
1795 let sock2
= or_panic
!(UnixDatagram
::unbound());
1796 or_panic
!(sock2
.connect(&path1
));
1798 let msg
= b
"hello world";
1799 or_panic
!(sock2
.send(msg
));
1800 let mut buf
= [0; 11];
1801 let size
= or_panic
!(sock1
.recv(&mut buf
));
1802 assert_eq
!(size
, 11);
1803 assert_eq
!(msg
, &buf
[..]);
1807 fn datagram_pair() {
1808 let msg1
= b
"hello";
1809 let msg2
= b
"world!";
1811 let (s1
, s2
) = or_panic
!(UnixDatagram
::pair());
1812 let thread
= thread
::spawn(move || {
1813 // s1 must be moved in or the test will hang!
1814 let mut buf
= [0; 5];
1815 or_panic
!(s1
.recv(&mut buf
));
1816 assert_eq
!(&msg1
[..], &buf
[..]);
1817 or_panic
!(s1
.send(msg2
));
1820 or_panic
!(s2
.send(msg1
));
1821 let mut buf
= [0; 6];
1822 or_panic
!(s2
.recv(&mut buf
));
1823 assert_eq
!(&msg2
[..], &buf
[..]);
1826 thread
.join().unwrap();
1829 // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
1830 // when passed zero Durations
1832 fn test_unix_datagram_timeout_zero_duration() {
1834 let path
= dir
.path().join("sock");
1836 let datagram
= or_panic
!(UnixDatagram
::bind(&path
));
1838 let result
= datagram
.set_write_timeout(Some(Duration
::new(0, 0)));
1839 let err
= result
.unwrap_err();
1840 assert_eq
!(err
.kind(), ErrorKind
::InvalidInput
);
1842 let result
= datagram
.set_read_timeout(Some(Duration
::new(0, 0)));
1843 let err
= result
.unwrap_err();
1844 assert_eq
!(err
.kind(), ErrorKind
::InvalidInput
);
1848 fn abstract_namespace_not_allowed() {
1849 assert
!(UnixStream
::connect("\0asdf").is_err());