1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 #![unstable(feature = "unix_socket", reason = "newly added", issue = "32312")]
12 //! Unix-specific networking functionality
23 use os
::unix
::ffi
::OsStrExt
;
24 use os
::unix
::io
::{RawFd, AsRawFd, FromRawFd, IntoRawFd}
;
29 use sys_common
::{AsInner, FromInner, IntoInner}
;
31 fn sun_path_offset() -> usize {
33 // Work with an actual instance of the type since using a null pointer is UB
34 let addr
: libc
::sockaddr_un
= mem
::uninitialized();
35 let base
= &addr
as *const _
as usize;
36 let path
= &addr
.sun_path
as *const _
as usize;
41 unsafe fn sockaddr_un(path
: &Path
) -> io
::Result
<(libc
::sockaddr_un
, libc
::socklen_t
)> {
42 let mut addr
: libc
::sockaddr_un
= mem
::zeroed();
43 addr
.sun_family
= libc
::AF_UNIX
as libc
::sa_family_t
;
45 let bytes
= path
.as_os_str().as_bytes();
47 if bytes
.contains(&0) {
48 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
49 "paths may not contain interior null bytes"));
52 if bytes
.len() >= addr
.sun_path
.len() {
53 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
54 "path must be shorter than SUN_LEN"));
56 for (dst
, src
) in addr
.sun_path
.iter_mut().zip(bytes
.iter()) {
57 *dst
= *src
as libc
::c_char
;
59 // null byte for pathname addresses is already there because we zeroed the
62 let mut len
= sun_path_offset() + bytes
.len();
67 Ok((addr
, len
as libc
::socklen_t
))
70 enum AddressKind
<'a
> {
76 /// An address associated with a Unix socket.
78 pub struct SocketAddr
{
79 addr
: libc
::sockaddr_un
,
84 fn new
<F
>(f
: F
) -> io
::Result
<SocketAddr
>
85 where F
: FnOnce(*mut libc
::sockaddr
, *mut libc
::socklen_t
) -> libc
::c_int
88 let mut addr
: libc
::sockaddr_un
= mem
::zeroed();
89 let mut len
= mem
::size_of
::<libc
::sockaddr_un
>() as libc
::socklen_t
;
90 cvt(f(&mut addr
as *mut _
as *mut _
, &mut len
))?
;
91 SocketAddr
::from_parts(addr
, len
)
95 fn from_parts(addr
: libc
::sockaddr_un
, mut len
: libc
::socklen_t
) -> io
::Result
<SocketAddr
> {
97 // When there is a datagram from unnamed unix socket
98 // linux returns zero bytes of address
99 len
= sun_path_offset() as libc
::socklen_t
; // i.e. zero-length address
100 } else if addr
.sun_family
!= libc
::AF_UNIX
as libc
::sa_family_t
{
101 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
102 "file descriptor did not correspond to a Unix socket"));
111 /// Returns true iff the address is unnamed.
112 pub fn is_unnamed(&self) -> bool
{
113 if let AddressKind
::Unnamed
= self.address() {
120 /// Returns the contents of this address if it is a `pathname` address.
121 pub fn as_pathname(&self) -> Option
<&Path
> {
122 if let AddressKind
::Pathname(path
) = self.address() {
129 fn address
<'a
>(&'a
self) -> AddressKind
<'a
> {
130 let len
= self.len
as usize - sun_path_offset();
131 let path
= unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) }
;
133 // OSX seems to return a len of 16 and a zeroed sun_path for unnamed addresses
134 if len
== 0 || (cfg
!(not(target_os
= "linux")) && self.addr
.sun_path
[0] == 0) {
136 } else if self.addr
.sun_path
[0] == 0 {
137 AddressKind
::Abstract(&path
[1..len
])
139 AddressKind
::Pathname(OsStr
::from_bytes(&path
[..len
- 1]).as_ref())
144 impl fmt
::Debug
for SocketAddr
{
145 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
146 match self.address() {
147 AddressKind
::Unnamed
=> write
!(fmt
, "(unnamed)"),
148 AddressKind
::Abstract(name
) => write
!(fmt
, "{} (abstract)", AsciiEscaped(name
)),
149 AddressKind
::Pathname(path
) => write
!(fmt
, "{:?} (pathname)", path
),
154 struct AsciiEscaped
<'a
>(&'a
[u8]);
156 impl<'a
> fmt
::Display
for AsciiEscaped
<'a
> {
157 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
159 for byte
in self.0.iter
().cloned().flat_map(ascii
::escape_default
) {
160 write
!(fmt
, "{}", byte
as char)?
;
166 /// A Unix stream socket.
171 /// #![feature(unix_socket)]
173 /// use std::os::unix::net::UnixStream;
174 /// use std::io::prelude::*;
176 /// let mut stream = UnixStream::connect("/path/to/my/socket").unwrap();
177 /// stream.write_all(b"hello world").unwrap();
178 /// let mut response = String::new();
179 /// stream.read_to_string(&mut response).unwrap();
180 /// println!("{}", response);
182 pub struct UnixStream(Socket
);
184 impl fmt
::Debug
for UnixStream
{
185 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
186 let mut builder
= fmt
.debug_struct("UnixStream");
187 builder
.field("fd", self.0.as_inner());
188 if let Ok(addr
) = self.local_addr() {
189 builder
.field("local", &addr
);
191 if let Ok(addr
) = self.peer_addr() {
192 builder
.field("peer", &addr
);
199 /// Connects to the socket named by `path`.
200 pub fn connect
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<UnixStream
> {
201 fn inner(path
: &Path
) -> io
::Result
<UnixStream
> {
203 let inner
= Socket
::new_raw(libc
::AF_UNIX
, libc
::SOCK_STREAM
)?
;
204 let (addr
, len
) = sockaddr_un(path
)?
;
206 cvt(libc
::connect(*inner
.as_inner(), &addr
as *const _
as *const _
, len
))?
;
207 Ok(UnixStream(inner
))
213 /// Creates an unnamed pair of connected sockets.
215 /// Returns two `UnixStream`s which are connected to each other.
216 pub fn pair() -> io
::Result
<(UnixStream
, UnixStream
)> {
217 let (i1
, i2
) = Socket
::new_pair(libc
::AF_UNIX
, libc
::SOCK_STREAM
)?
;
218 Ok((UnixStream(i1
), UnixStream(i2
)))
221 /// Creates a new independently owned handle to the underlying socket.
223 /// The returned `UnixStream` is a reference to the same stream that this
224 /// object references. Both handles will read and write the same stream of
225 /// data, and options set on one stream will be propogated to the other
227 pub fn try_clone(&self) -> io
::Result
<UnixStream
> {
228 self.0.duplicate().map(UnixStream
)
231 /// Returns the socket address of the local half of this connection.
232 pub fn local_addr(&self) -> io
::Result
<SocketAddr
> {
233 SocketAddr
::new(|addr
, len
| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }
)
236 /// Returns the socket address of the remote half of this connection.
237 pub fn peer_addr(&self) -> io
::Result
<SocketAddr
> {
238 SocketAddr
::new(|addr
, len
| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) }
)
241 /// Sets the read timeout for the socket.
243 /// If the provided value is `None`, then `read` calls will block
244 /// indefinitely. It is an error to pass the zero `Duration` to this
246 pub fn set_read_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
247 self.0.set_timeout(timeout
, libc
::SO_RCVTIMEO
)
250 /// Sets the write timeout for the socket.
252 /// If the provided value is `None`, then `write` calls will block
253 /// indefinitely. It is an error to pass the zero `Duration` to this
255 pub fn set_write_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
256 self.0.set_timeout(timeout
, libc
::SO_SNDTIMEO
)
259 /// Returns the read timeout of this socket.
260 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
261 self.0.timeout(libc
::SO_RCVTIMEO
)
264 /// Returns the write timeout of this socket.
265 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
266 self.0.timeout(libc
::SO_SNDTIMEO
)
269 /// Moves the socket into or out of nonblocking mode.
270 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
271 self.0.set_nonblocking(nonblocking
)
274 /// Returns the value of the `SO_ERROR` option.
275 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
279 /// Shuts down the read, write, or both halves of this connection.
281 /// This function will cause all pending and future I/O calls on the
282 /// specified portions to immediately return with an appropriate value
283 /// (see the documentation of `Shutdown`).
284 pub fn shutdown(&self, how
: Shutdown
) -> io
::Result
<()> {
289 impl io
::Read
for UnixStream
{
290 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
291 io
::Read
::read(&mut &*self, buf
)
294 fn read_to_end(&mut self, buf
: &mut Vec
<u8>) -> io
::Result
<usize> {
295 io
::Read
::read_to_end(&mut &*self, buf
)
299 impl<'a
> io
::Read
for &'a UnixStream
{
300 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
304 fn read_to_end(&mut self, buf
: &mut Vec
<u8>) -> io
::Result
<usize> {
305 self.0.read_to_end(buf
)
309 impl io
::Write
for UnixStream
{
310 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
311 io
::Write
::write(&mut &*self, buf
)
314 fn flush(&mut self) -> io
::Result
<()> {
315 io
::Write
::flush(&mut &*self)
319 impl<'a
> io
::Write
for &'a UnixStream
{
320 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
324 fn flush(&mut self) -> io
::Result
<()> {
329 impl AsRawFd
for UnixStream
{
330 fn as_raw_fd(&self) -> RawFd
{
335 impl FromRawFd
for UnixStream
{
336 unsafe fn from_raw_fd(fd
: RawFd
) -> UnixStream
{
337 UnixStream(Socket
::from_inner(fd
))
341 impl IntoRawFd
for UnixStream
{
342 fn into_raw_fd(self) -> RawFd
{
347 /// A structure representing a Unix domain socket server.
352 /// #![feature(unix_socket)]
355 /// use std::os::unix::net::{UnixStream, UnixListener};
357 /// fn handle_client(stream: UnixStream) {
361 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
363 /// // accept connections and process them, spawning a new thread for each one
364 /// for stream in listener.incoming() {
367 /// /* connection succeeded */
368 /// thread::spawn(|| handle_client(stream));
371 /// /* connection failed */
377 /// // close the listener socket
380 pub struct UnixListener(Socket
);
382 impl fmt
::Debug
for UnixListener
{
383 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
384 let mut builder
= fmt
.debug_struct("UnixListener");
385 builder
.field("fd", self.0.as_inner());
386 if let Ok(addr
) = self.local_addr() {
387 builder
.field("local", &addr
);
394 /// Creates a new `UnixListener` bound to the specified socket.
395 pub fn bind
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<UnixListener
> {
396 fn inner(path
: &Path
) -> io
::Result
<UnixListener
> {
398 let inner
= Socket
::new_raw(libc
::AF_UNIX
, libc
::SOCK_STREAM
)?
;
399 let (addr
, len
) = sockaddr_un(path
)?
;
401 cvt(libc
::bind(*inner
.as_inner(), &addr
as *const _
as *const _
, len
))?
;
402 cvt(libc
::listen(*inner
.as_inner(), 128))?
;
404 Ok(UnixListener(inner
))
410 /// Accepts a new incoming connection to this listener.
412 /// This function will block the calling thread until a new Unix connection
413 /// is established. When established, the corersponding `UnixStream` and
414 /// the remote peer's address will be returned.
415 pub fn accept(&self) -> io
::Result
<(UnixStream
, SocketAddr
)> {
416 let mut storage
: libc
::sockaddr_un
= unsafe { mem::zeroed() }
;
417 let mut len
= mem
::size_of_val(&storage
) as libc
::socklen_t
;
418 let sock
= self.0.accept(&mut storage
as *mut _
as *mut _
, &mut len
)?
;
419 let addr
= SocketAddr
::from_parts(storage
, len
)?
;
420 Ok((UnixStream(sock
), addr
))
423 /// Creates a new independently owned handle to the underlying socket.
425 /// The returned `UnixListener` is a reference to the same socket that this
426 /// object references. Both handles can be used to accept incoming
427 /// connections and options set on one listener will affect the other.
428 pub fn try_clone(&self) -> io
::Result
<UnixListener
> {
429 self.0.duplicate().map(UnixListener
)
432 /// Returns the local socket address of this listener.
433 pub fn local_addr(&self) -> io
::Result
<SocketAddr
> {
434 SocketAddr
::new(|addr
, len
| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }
)
437 /// Moves the socket into or out of nonblocking mode.
438 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
439 self.0.set_nonblocking(nonblocking
)
442 /// Returns the value of the `SO_ERROR` option.
443 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
447 /// Returns an iterator over incoming connections.
449 /// The iterator will never return `None` and will also not yield the
450 /// peer's `SocketAddr` structure.
451 pub fn incoming
<'a
>(&'a
self) -> Incoming
<'a
> {
452 Incoming { listener: self }
456 impl AsRawFd
for UnixListener
{
457 fn as_raw_fd(&self) -> RawFd
{
462 impl FromRawFd
for UnixListener
{
463 unsafe fn from_raw_fd(fd
: RawFd
) -> UnixListener
{
464 UnixListener(Socket
::from_inner(fd
))
468 impl IntoRawFd
for UnixListener
{
469 fn into_raw_fd(self) -> RawFd
{
474 impl<'a
> IntoIterator
for &'a UnixListener
{
475 type Item
= io
::Result
<UnixStream
>;
476 type IntoIter
= Incoming
<'a
>;
478 fn into_iter(self) -> Incoming
<'a
> {
483 /// An iterator over incoming connections to a `UnixListener`.
485 /// It will never return `None`.
487 pub struct Incoming
<'a
> {
488 listener
: &'a UnixListener
,
491 impl<'a
> Iterator
for Incoming
<'a
> {
492 type Item
= io
::Result
<UnixStream
>;
494 fn next(&mut self) -> Option
<io
::Result
<UnixStream
>> {
495 Some(self.listener
.accept().map(|s
| s
.0))
498 fn size_hint(&self) -> (usize, Option
<usize>) {
499 (usize::max_value(), None
)
503 /// A Unix datagram socket.
508 /// #![feature(unix_socket)]
510 /// use std::os::unix::net::UnixDatagram;
512 /// let socket = UnixDatagram::bind("/path/to/my/socket").unwrap();
513 /// socket.send_to(b"hello world", "/path/to/other/socket").unwrap();
514 /// let mut buf = [0; 100];
515 /// let (count, address) = socket.recv_from(&mut buf).unwrap();
516 /// println!("socket {:?} sent {:?}", address, &buf[..count]);
518 pub struct UnixDatagram(Socket
);
520 impl fmt
::Debug
for UnixDatagram
{
521 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
522 let mut builder
= fmt
.debug_struct("UnixDatagram");
523 builder
.field("fd", self.0.as_inner());
524 if let Ok(addr
) = self.local_addr() {
525 builder
.field("local", &addr
);
527 if let Ok(addr
) = self.peer_addr() {
528 builder
.field("peer", &addr
);
535 /// Creates a Unix datagram socket bound to the given path.
536 pub fn bind
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<UnixDatagram
> {
537 fn inner(path
: &Path
) -> io
::Result
<UnixDatagram
> {
539 let socket
= UnixDatagram
::unbound()?
;
540 let (addr
, len
) = sockaddr_un(path
)?
;
542 cvt(libc
::bind(*socket
.0.as_inner(), &addr
as *const _
as *const _
, len
))?
;
550 /// Creates a Unix Datagram socket which is not bound to any address.
551 pub fn unbound() -> io
::Result
<UnixDatagram
> {
552 let inner
= Socket
::new_raw(libc
::AF_UNIX
, libc
::SOCK_DGRAM
)?
;
553 Ok(UnixDatagram(inner
))
556 /// Create an unnamed pair of connected sockets.
558 /// Returns two `UnixDatagrams`s which are connected to each other.
559 pub fn pair() -> io
::Result
<(UnixDatagram
, UnixDatagram
)> {
560 let (i1
, i2
) = Socket
::new_pair(libc
::AF_UNIX
, libc
::SOCK_DGRAM
)?
;
561 Ok((UnixDatagram(i1
), UnixDatagram(i2
)))
564 /// Connects the socket to the specified address.
566 /// The `send` method may be used to send data to the specified address.
567 /// `recv` and `recv_from` will only receive data from that address.
568 pub fn connect
<P
: AsRef
<Path
>>(&self, path
: P
) -> io
::Result
<()> {
569 fn inner(d
: &UnixDatagram
, path
: &Path
) -> io
::Result
<()> {
571 let (addr
, len
) = sockaddr_un(path
)?
;
573 cvt(libc
::connect(*d
.0.as_inner(), &addr
as *const _
as *const _
, len
))?
;
578 inner(self, path
.as_ref())
581 /// Creates a new independently owned handle to the underlying socket.
583 /// The returned `UnixListener` is a reference to the same socket that this
584 /// object references. Both handles can be used to accept incoming
585 /// connections and options set on one listener will affect the other.
586 pub fn try_clone(&self) -> io
::Result
<UnixDatagram
> {
587 self.0.duplicate().map(UnixDatagram
)
590 /// Returns the address of this socket.
591 pub fn local_addr(&self) -> io
::Result
<SocketAddr
> {
592 SocketAddr
::new(|addr
, len
| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }
)
595 /// Returns the address of this socket's peer.
597 /// The `connect` method will connect the socket to a peer.
598 pub fn peer_addr(&self) -> io
::Result
<SocketAddr
> {
599 SocketAddr
::new(|addr
, len
| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) }
)
602 /// Receives data from the socket.
604 /// On success, returns the number of bytes read and the address from
605 /// whence the data came.
606 pub fn recv_from(&self, buf
: &mut [u8]) -> io
::Result
<(usize, SocketAddr
)> {
608 let addr
= SocketAddr
::new(|addr
, len
| {
610 count
= libc
::recvfrom(*self.0.as_inner(),
611 buf
.as_mut_ptr() as *mut _
,
618 } else if count
== 0 {
626 Ok((count
as usize, addr
))
629 /// Receives data from the socket.
631 /// On success, returns the number of bytes read.
632 pub fn recv(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
636 /// Sends data on the socket to the specified address.
638 /// On success, returns the number of bytes written.
639 pub fn send_to
<P
: AsRef
<Path
>>(&self, buf
: &[u8], path
: P
) -> io
::Result
<usize> {
640 fn inner(d
: &UnixDatagram
, buf
: &[u8], path
: &Path
) -> io
::Result
<usize> {
642 let (addr
, len
) = sockaddr_un(path
)?
;
644 let count
= cvt(libc
::sendto(*d
.0.as_inner(),
645 buf
.as_ptr() as *const _
,
648 &addr
as *const _
as *const _
,
653 inner(self, buf
, path
.as_ref())
656 /// Sends data on the socket to the socket's peer.
658 /// The peer address may be set by the `connect` method, and this method
659 /// will return an error if the socket has not already been connected.
661 /// On success, returns the number of bytes written.
662 pub fn send(&self, buf
: &[u8]) -> io
::Result
<usize> {
666 /// Sets the read timeout for the socket.
668 /// If the provided value is `None`, then `recv` and `recv_from` calls will
669 /// block indefinitely. It is an error to pass the zero `Duration` to this
671 pub fn set_read_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
672 self.0.set_timeout(timeout
, libc
::SO_RCVTIMEO
)
675 /// Sets the write timeout for the socket.
677 /// If the provided value is `None`, then `send` and `send_to` calls will
678 /// block indefinitely. It is an error to pass the zero `Duration` to this
680 pub fn set_write_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
681 self.0.set_timeout(timeout
, libc
::SO_SNDTIMEO
)
684 /// Returns the read timeout of this socket.
685 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
686 self.0.timeout(libc
::SO_RCVTIMEO
)
689 /// Returns the write timeout of this socket.
690 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
691 self.0.timeout(libc
::SO_SNDTIMEO
)
694 /// Moves the socket into or out of nonblocking mode.
695 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
696 self.0.set_nonblocking(nonblocking
)
699 /// Returns the value of the `SO_ERROR` option.
700 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
704 /// Shut down the read, write, or both halves of this connection.
706 /// This function will cause all pending and future I/O calls on the
707 /// specified portions to immediately return with an appropriate value
708 /// (see the documentation of `Shutdown`).
709 pub fn shutdown(&self, how
: Shutdown
) -> io
::Result
<()> {
714 impl AsRawFd
for UnixDatagram
{
715 fn as_raw_fd(&self) -> RawFd
{
720 impl FromRawFd
for UnixDatagram
{
721 unsafe fn from_raw_fd(fd
: RawFd
) -> UnixDatagram
{
722 UnixDatagram(Socket
::from_inner(fd
))
726 impl IntoRawFd
for UnixDatagram
{
727 fn into_raw_fd(self) -> RawFd
{
739 use sys_common
::io
::test
::tmpdir
;
743 macro_rules
! or_panic
{
747 Err(e
) => panic
!("{}", e
),
755 let socket_path
= dir
.path().join("sock");
757 let msg2
= b
"world!";
759 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
760 let thread
= thread
::spawn(move || {
761 let mut stream
= or_panic
!(listener
.accept()).0;
762 let mut buf
= [0; 5];
763 or_panic
!(stream
.read(&mut buf
));
764 assert_eq
!(&msg1
[..], &buf
[..]);
765 or_panic
!(stream
.write_all(msg2
));
768 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
769 assert_eq
!(Some(&*socket_path
),
770 stream
.peer_addr().unwrap().as_pathname());
771 or_panic
!(stream
.write_all(msg1
));
772 let mut buf
= vec
![];
773 or_panic
!(stream
.read_to_end(&mut buf
));
774 assert_eq
!(&msg2
[..], &buf
[..]);
777 thread
.join().unwrap();
783 let msg2
= b
"world!";
785 let (mut s1
, mut s2
) = or_panic
!(UnixStream
::pair());
786 let thread
= thread
::spawn(move || {
787 // s1 must be moved in or the test will hang!
788 let mut buf
= [0; 5];
789 or_panic
!(s1
.read(&mut buf
));
790 assert_eq
!(&msg1
[..], &buf
[..]);
791 or_panic
!(s1
.write_all(msg2
));
794 or_panic
!(s2
.write_all(msg1
));
795 let mut buf
= vec
![];
796 or_panic
!(s2
.read_to_end(&mut buf
));
797 assert_eq
!(&msg2
[..], &buf
[..]);
800 thread
.join().unwrap();
806 let socket_path
= dir
.path().join("sock");
810 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
811 let thread
= thread
::spawn(move || {
812 let mut stream
= or_panic
!(listener
.accept()).0;
813 or_panic
!(stream
.write_all(msg1
));
814 or_panic
!(stream
.write_all(msg2
));
817 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
818 let mut stream2
= or_panic
!(stream
.try_clone());
820 let mut buf
= [0; 5];
821 or_panic
!(stream
.read(&mut buf
));
822 assert_eq
!(&msg1
[..], &buf
[..]);
823 or_panic
!(stream2
.read(&mut buf
));
824 assert_eq
!(&msg2
[..], &buf
[..]);
826 thread
.join().unwrap();
832 let socket_path
= dir
.path().join("sock");
834 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
835 let thread
= thread
::spawn(move || {
836 for stream
in listener
.incoming().take(2) {
837 let mut stream
= or_panic
!(stream
);
839 or_panic
!(stream
.read(&mut buf
));
844 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
845 or_panic
!(stream
.write_all(&[0]));
848 thread
.join().unwrap();
854 let socket_path
= dir
.path()
855 .join("asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\
856 sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf");
857 match UnixStream
::connect(&socket_path
) {
858 Err(ref e
) if e
.kind() == io
::ErrorKind
::InvalidInput
=> {}
859 Err(e
) => panic
!("unexpected error {}", e
),
860 Ok(_
) => panic
!("unexpected success"),
863 match UnixListener
::bind(&socket_path
) {
864 Err(ref e
) if e
.kind() == io
::ErrorKind
::InvalidInput
=> {}
865 Err(e
) => panic
!("unexpected error {}", e
),
866 Ok(_
) => panic
!("unexpected success"),
869 match UnixDatagram
::bind(&socket_path
) {
870 Err(ref e
) if e
.kind() == io
::ErrorKind
::InvalidInput
=> {}
871 Err(e
) => panic
!("unexpected error {}", e
),
872 Ok(_
) => panic
!("unexpected success"),
879 let socket_path
= dir
.path().join("sock");
881 let _listener
= or_panic
!(UnixListener
::bind(&socket_path
));
883 let stream
= or_panic
!(UnixStream
::connect(&socket_path
));
884 let dur
= Duration
::new(15410, 0);
886 assert_eq
!(None
, or_panic
!(stream
.read_timeout()));
888 or_panic
!(stream
.set_read_timeout(Some(dur
)));
889 assert_eq
!(Some(dur
), or_panic
!(stream
.read_timeout()));
891 assert_eq
!(None
, or_panic
!(stream
.write_timeout()));
893 or_panic
!(stream
.set_write_timeout(Some(dur
)));
894 assert_eq
!(Some(dur
), or_panic
!(stream
.write_timeout()));
896 or_panic
!(stream
.set_read_timeout(None
));
897 assert_eq
!(None
, or_panic
!(stream
.read_timeout()));
899 or_panic
!(stream
.set_write_timeout(None
));
900 assert_eq
!(None
, or_panic
!(stream
.write_timeout()));
904 fn test_read_timeout() {
906 let socket_path
= dir
.path().join("sock");
908 let _listener
= or_panic
!(UnixListener
::bind(&socket_path
));
910 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
911 or_panic
!(stream
.set_read_timeout(Some(Duration
::from_millis(1000))));
913 let mut buf
= [0; 10];
914 let kind
= stream
.read(&mut buf
).err().expect("expected error").kind();
915 assert
!(kind
== io
::ErrorKind
::WouldBlock
|| kind
== io
::ErrorKind
::TimedOut
);
919 fn test_read_with_timeout() {
921 let socket_path
= dir
.path().join("sock");
923 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
925 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
926 or_panic
!(stream
.set_read_timeout(Some(Duration
::from_millis(1000))));
928 let mut other_end
= or_panic
!(listener
.accept()).0;
929 or_panic
!(other_end
.write_all(b
"hello world"));
931 let mut buf
= [0; 11];
932 or_panic
!(stream
.read(&mut buf
));
933 assert_eq
!(b
"hello world", &buf
[..]);
935 let kind
= stream
.read(&mut buf
).err().expect("expected error").kind();
936 assert
!(kind
== io
::ErrorKind
::WouldBlock
|| kind
== io
::ErrorKind
::TimedOut
);
940 fn test_unix_datagram() {
942 let path1
= dir
.path().join("sock1");
943 let path2
= dir
.path().join("sock2");
945 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
946 let sock2
= or_panic
!(UnixDatagram
::bind(&path2
));
948 let msg
= b
"hello world";
949 or_panic
!(sock1
.send_to(msg
, &path2
));
950 let mut buf
= [0; 11];
951 or_panic
!(sock2
.recv_from(&mut buf
));
952 assert_eq
!(msg
, &buf
[..]);
956 fn test_unnamed_unix_datagram() {
958 let path1
= dir
.path().join("sock1");
960 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
961 let sock2
= or_panic
!(UnixDatagram
::unbound());
963 let msg
= b
"hello world";
964 or_panic
!(sock2
.send_to(msg
, &path1
));
965 let mut buf
= [0; 11];
966 let (usize, addr
) = or_panic
!(sock1
.recv_from(&mut buf
));
967 assert_eq
!(usize, 11);
968 assert
!(addr
.is_unnamed());
969 assert_eq
!(msg
, &buf
[..]);
973 fn test_connect_unix_datagram() {
975 let path1
= dir
.path().join("sock1");
976 let path2
= dir
.path().join("sock2");
978 let bsock1
= or_panic
!(UnixDatagram
::bind(&path1
));
979 let bsock2
= or_panic
!(UnixDatagram
::bind(&path2
));
980 let sock
= or_panic
!(UnixDatagram
::unbound());
981 or_panic
!(sock
.connect(&path1
));
984 let msg
= b
"hello there";
985 or_panic
!(sock
.send(msg
));
986 let mut buf
= [0; 11];
987 let (usize, addr
) = or_panic
!(bsock1
.recv_from(&mut buf
));
988 assert_eq
!(usize, 11);
989 assert
!(addr
.is_unnamed());
990 assert_eq
!(msg
, &buf
[..]);
992 // Changing default socket works too
993 or_panic
!(sock
.connect(&path2
));
994 or_panic
!(sock
.send(msg
));
995 or_panic
!(bsock2
.recv_from(&mut buf
));
999 fn test_unix_datagram_recv() {
1001 let path1
= dir
.path().join("sock1");
1003 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
1004 let sock2
= or_panic
!(UnixDatagram
::unbound());
1005 or_panic
!(sock2
.connect(&path1
));
1007 let msg
= b
"hello world";
1008 or_panic
!(sock2
.send(msg
));
1009 let mut buf
= [0; 11];
1010 let size
= or_panic
!(sock1
.recv(&mut buf
));
1011 assert_eq
!(size
, 11);
1012 assert_eq
!(msg
, &buf
[..]);
1016 fn datagram_pair() {
1017 let msg1
= b
"hello";
1018 let msg2
= b
"world!";
1020 let (s1
, s2
) = or_panic
!(UnixDatagram
::pair());
1021 let thread
= thread
::spawn(move || {
1022 // s1 must be moved in or the test will hang!
1023 let mut buf
= [0; 5];
1024 or_panic
!(s1
.recv(&mut buf
));
1025 assert_eq
!(&msg1
[..], &buf
[..]);
1026 or_panic
!(s1
.send(msg2
));
1029 or_panic
!(s2
.send(msg1
));
1030 let mut buf
= [0; 6];
1031 or_panic
!(s2
.recv(&mut buf
));
1032 assert_eq
!(&msg2
[..], &buf
[..]);
1035 thread
.join().unwrap();
1039 fn abstract_namespace_not_allowed() {
1040 assert
!(UnixStream
::connect("\0asdf").is_err());