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.
11 #![stable(feature = "unix_socket", since = "1.10.0")]
13 //! 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 #[cfg(any(target_os = "linux", target_os = "android",
32 target_os
= "dragonfly", target_os
= "freebsd",
33 target_os
= "openbsd", target_os
= "netbsd",
34 target_os
= "haiku", target_os
= "bitrig"))]
35 use libc
::MSG_NOSIGNAL
;
36 #[cfg(not(any(target_os = "linux", target_os = "android",
37 target_os
= "dragonfly", target_os
= "freebsd",
38 target_os
= "openbsd", target_os
= "netbsd",
39 target_os
= "haiku", target_os
= "bitrig")))]
40 const MSG_NOSIGNAL
: libc
::c_int
= 0x0;
42 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
= mem
::uninitialized();
46 let base
= &addr
as *const _
as usize;
47 let path
= &addr
.sun_path
as *const _
as usize;
52 unsafe fn sockaddr_un(path
: &Path
) -> io
::Result
<(libc
::sockaddr_un
, libc
::socklen_t
)> {
53 let mut addr
: libc
::sockaddr_un
= mem
::zeroed();
54 addr
.sun_family
= libc
::AF_UNIX
as libc
::sa_family_t
;
56 let bytes
= path
.as_os_str().as_bytes();
58 if bytes
.contains(&0) {
59 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
60 "paths may not contain interior null bytes"));
63 if bytes
.len() >= addr
.sun_path
.len() {
64 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
65 "path must be shorter than SUN_LEN"));
67 for (dst
, src
) in addr
.sun_path
.iter_mut().zip(bytes
.iter()) {
68 *dst
= *src
as libc
::c_char
;
70 // null byte for pathname addresses is already there because we zeroed the
73 let mut len
= sun_path_offset() + bytes
.len();
78 Ok((addr
, len
as libc
::socklen_t
))
81 enum AddressKind
<'a
> {
87 /// An address associated with a Unix socket.
89 #[stable(feature = "unix_socket", since = "1.10.0")]
90 pub struct SocketAddr
{
91 addr
: libc
::sockaddr_un
,
96 fn new
<F
>(f
: F
) -> io
::Result
<SocketAddr
>
97 where F
: FnOnce(*mut libc
::sockaddr
, *mut libc
::socklen_t
) -> libc
::c_int
100 let mut addr
: libc
::sockaddr_un
= mem
::zeroed();
101 let mut len
= mem
::size_of
::<libc
::sockaddr_un
>() as libc
::socklen_t
;
102 cvt(f(&mut addr
as *mut _
as *mut _
, &mut len
))?
;
103 SocketAddr
::from_parts(addr
, len
)
107 fn from_parts(addr
: libc
::sockaddr_un
, mut len
: libc
::socklen_t
) -> io
::Result
<SocketAddr
> {
109 // When there is a datagram from unnamed unix socket
110 // linux returns zero bytes of address
111 len
= sun_path_offset() as libc
::socklen_t
; // i.e. zero-length address
112 } else if addr
.sun_family
!= libc
::AF_UNIX
as libc
::sa_family_t
{
113 return Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
,
114 "file descriptor did not correspond to a Unix socket"));
123 /// Returns true if and only if the address is unnamed.
124 #[stable(feature = "unix_socket", since = "1.10.0")]
125 pub fn is_unnamed(&self) -> bool
{
126 if let AddressKind
::Unnamed
= self.address() {
133 /// Returns the contents of this address if it is a `pathname` address.
134 #[stable(feature = "unix_socket", since = "1.10.0")]
135 pub fn as_pathname(&self) -> Option
<&Path
> {
136 if let AddressKind
::Pathname(path
) = self.address() {
143 fn address
<'a
>(&'a
self) -> AddressKind
<'a
> {
144 let len
= self.len
as usize - sun_path_offset();
145 let path
= unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) }
;
147 // OSX seems to return a len of 16 and a zeroed sun_path for unnamed addresses
148 if len
== 0 || (cfg
!(not(target_os
= "linux")) && self.addr
.sun_path
[0] == 0) {
150 } else if self.addr
.sun_path
[0] == 0 {
151 AddressKind
::Abstract(&path
[1..len
])
153 AddressKind
::Pathname(OsStr
::from_bytes(&path
[..len
- 1]).as_ref())
158 #[stable(feature = "unix_socket", since = "1.10.0")]
159 impl fmt
::Debug
for SocketAddr
{
160 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
161 match self.address() {
162 AddressKind
::Unnamed
=> write
!(fmt
, "(unnamed)"),
163 AddressKind
::Abstract(name
) => write
!(fmt
, "{} (abstract)", AsciiEscaped(name
)),
164 AddressKind
::Pathname(path
) => write
!(fmt
, "{:?} (pathname)", path
),
169 struct AsciiEscaped
<'a
>(&'a
[u8]);
171 impl<'a
> fmt
::Display
for AsciiEscaped
<'a
> {
172 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
174 for byte
in self.0.iter
().cloned().flat_map(ascii
::escape_default
) {
175 write
!(fmt
, "{}", byte
as char)?
;
181 /// A Unix stream socket.
186 /// use std::os::unix::net::UnixStream;
187 /// use std::io::prelude::*;
189 /// let mut stream = UnixStream::connect("/path/to/my/socket").unwrap();
190 /// stream.write_all(b"hello world").unwrap();
191 /// let mut response = String::new();
192 /// stream.read_to_string(&mut response).unwrap();
193 /// println!("{}", response);
195 #[stable(feature = "unix_socket", since = "1.10.0")]
196 pub struct UnixStream(Socket
);
198 #[stable(feature = "unix_socket", since = "1.10.0")]
199 impl fmt
::Debug
for UnixStream
{
200 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
201 let mut builder
= fmt
.debug_struct("UnixStream");
202 builder
.field("fd", self.0.as_inner());
203 if let Ok(addr
) = self.local_addr() {
204 builder
.field("local", &addr
);
206 if let Ok(addr
) = self.peer_addr() {
207 builder
.field("peer", &addr
);
214 /// Connects to the socket named by `path`.
215 #[stable(feature = "unix_socket", since = "1.10.0")]
216 pub fn connect
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<UnixStream
> {
217 fn inner(path
: &Path
) -> io
::Result
<UnixStream
> {
219 let inner
= Socket
::new_raw(libc
::AF_UNIX
, libc
::SOCK_STREAM
)?
;
220 let (addr
, len
) = sockaddr_un(path
)?
;
222 cvt(libc
::connect(*inner
.as_inner(), &addr
as *const _
as *const _
, len
))?
;
223 Ok(UnixStream(inner
))
229 /// Creates an unnamed pair of connected sockets.
231 /// Returns two `UnixStream`s which are connected to each other.
232 #[stable(feature = "unix_socket", since = "1.10.0")]
233 pub fn pair() -> io
::Result
<(UnixStream
, UnixStream
)> {
234 let (i1
, i2
) = Socket
::new_pair(libc
::AF_UNIX
, libc
::SOCK_STREAM
)?
;
235 Ok((UnixStream(i1
), UnixStream(i2
)))
238 /// Creates a new independently owned handle to the underlying socket.
240 /// The returned `UnixStream` is a reference to the same stream that this
241 /// object references. Both handles will read and write the same stream of
242 /// data, and options set on one stream will be propogated to the other
244 #[stable(feature = "unix_socket", since = "1.10.0")]
245 pub fn try_clone(&self) -> io
::Result
<UnixStream
> {
246 self.0.duplicate().map(UnixStream
)
249 /// Returns the socket address of the local half of this connection.
250 #[stable(feature = "unix_socket", since = "1.10.0")]
251 pub fn local_addr(&self) -> io
::Result
<SocketAddr
> {
252 SocketAddr
::new(|addr
, len
| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }
)
255 /// Returns the socket address of the remote half of this connection.
256 #[stable(feature = "unix_socket", since = "1.10.0")]
257 pub fn peer_addr(&self) -> io
::Result
<SocketAddr
> {
258 SocketAddr
::new(|addr
, len
| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) }
)
261 /// Sets the read timeout for the socket.
263 /// If the provided value is `None`, then `read` calls will block
264 /// indefinitely. It is an error to pass the zero `Duration` to this
266 #[stable(feature = "unix_socket", since = "1.10.0")]
267 pub fn set_read_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
268 self.0.set_timeout(timeout
, libc
::SO_RCVTIMEO
)
271 /// Sets the write timeout for the socket.
273 /// If the provided value is `None`, then `write` calls will block
274 /// indefinitely. It is an error to pass the zero `Duration` to this
276 #[stable(feature = "unix_socket", since = "1.10.0")]
277 pub fn set_write_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
278 self.0.set_timeout(timeout
, libc
::SO_SNDTIMEO
)
281 /// Returns the read timeout of this socket.
282 #[stable(feature = "unix_socket", since = "1.10.0")]
283 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
284 self.0.timeout(libc
::SO_RCVTIMEO
)
287 /// Returns the write timeout of this socket.
288 #[stable(feature = "unix_socket", since = "1.10.0")]
289 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
290 self.0.timeout(libc
::SO_SNDTIMEO
)
293 /// Moves the socket into or out of nonblocking mode.
294 #[stable(feature = "unix_socket", since = "1.10.0")]
295 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
296 self.0.set_nonblocking(nonblocking
)
299 /// Returns the value of the `SO_ERROR` option.
300 #[stable(feature = "unix_socket", since = "1.10.0")]
301 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
305 /// Shuts down the read, write, or both halves of this connection.
307 /// This function will cause all pending and future I/O calls on the
308 /// specified portions to immediately return with an appropriate value
309 /// (see the documentation of `Shutdown`).
310 #[stable(feature = "unix_socket", since = "1.10.0")]
311 pub fn shutdown(&self, how
: Shutdown
) -> io
::Result
<()> {
316 #[stable(feature = "unix_socket", since = "1.10.0")]
317 impl io
::Read
for UnixStream
{
318 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
319 io
::Read
::read(&mut &*self, buf
)
322 fn read_to_end(&mut self, buf
: &mut Vec
<u8>) -> io
::Result
<usize> {
323 io
::Read
::read_to_end(&mut &*self, buf
)
327 #[stable(feature = "unix_socket", since = "1.10.0")]
328 impl<'a
> io
::Read
for &'a UnixStream
{
329 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
333 fn read_to_end(&mut self, buf
: &mut Vec
<u8>) -> io
::Result
<usize> {
334 self.0.read_to_end(buf
)
338 #[stable(feature = "unix_socket", since = "1.10.0")]
339 impl io
::Write
for UnixStream
{
340 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
341 io
::Write
::write(&mut &*self, buf
)
344 fn flush(&mut self) -> io
::Result
<()> {
345 io
::Write
::flush(&mut &*self)
349 #[stable(feature = "unix_socket", since = "1.10.0")]
350 impl<'a
> io
::Write
for &'a UnixStream
{
351 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
355 fn flush(&mut self) -> io
::Result
<()> {
360 #[stable(feature = "unix_socket", since = "1.10.0")]
361 impl AsRawFd
for UnixStream
{
362 fn as_raw_fd(&self) -> RawFd
{
367 #[stable(feature = "unix_socket", since = "1.10.0")]
368 impl FromRawFd
for UnixStream
{
369 unsafe fn from_raw_fd(fd
: RawFd
) -> UnixStream
{
370 UnixStream(Socket
::from_inner(fd
))
374 #[stable(feature = "unix_socket", since = "1.10.0")]
375 impl IntoRawFd
for UnixStream
{
376 fn into_raw_fd(self) -> RawFd
{
381 /// A structure representing a Unix domain socket server.
387 /// use std::os::unix::net::{UnixStream, UnixListener};
389 /// fn handle_client(stream: UnixStream) {
393 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
395 /// // accept connections and process them, spawning a new thread for each one
396 /// for stream in listener.incoming() {
399 /// /* connection succeeded */
400 /// thread::spawn(|| handle_client(stream));
403 /// /* connection failed */
409 /// // close the listener socket
412 #[stable(feature = "unix_socket", since = "1.10.0")]
413 pub struct UnixListener(Socket
);
415 #[stable(feature = "unix_socket", since = "1.10.0")]
416 impl fmt
::Debug
for UnixListener
{
417 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
418 let mut builder
= fmt
.debug_struct("UnixListener");
419 builder
.field("fd", self.0.as_inner());
420 if let Ok(addr
) = self.local_addr() {
421 builder
.field("local", &addr
);
428 /// Creates a new `UnixListener` bound to the specified socket.
429 #[stable(feature = "unix_socket", since = "1.10.0")]
430 pub fn bind
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<UnixListener
> {
431 fn inner(path
: &Path
) -> io
::Result
<UnixListener
> {
433 let inner
= Socket
::new_raw(libc
::AF_UNIX
, libc
::SOCK_STREAM
)?
;
434 let (addr
, len
) = sockaddr_un(path
)?
;
436 cvt(libc
::bind(*inner
.as_inner(), &addr
as *const _
as *const _
, len
))?
;
437 cvt(libc
::listen(*inner
.as_inner(), 128))?
;
439 Ok(UnixListener(inner
))
445 /// Accepts a new incoming connection to this listener.
447 /// This function will block the calling thread until a new Unix connection
448 /// is established. When established, the corersponding `UnixStream` and
449 /// the remote peer's address will be returned.
450 #[stable(feature = "unix_socket", since = "1.10.0")]
451 pub fn accept(&self) -> io
::Result
<(UnixStream
, SocketAddr
)> {
452 let mut storage
: libc
::sockaddr_un
= unsafe { mem::zeroed() }
;
453 let mut len
= mem
::size_of_val(&storage
) as libc
::socklen_t
;
454 let sock
= self.0.accept(&mut storage
as *mut _
as *mut _
, &mut len
)?
;
455 let addr
= SocketAddr
::from_parts(storage
, len
)?
;
456 Ok((UnixStream(sock
), addr
))
459 /// Creates a new independently owned handle to the underlying socket.
461 /// The returned `UnixListener` is a reference to the same socket that this
462 /// object references. Both handles can be used to accept incoming
463 /// connections and options set on one listener will affect the other.
464 #[stable(feature = "unix_socket", since = "1.10.0")]
465 pub fn try_clone(&self) -> io
::Result
<UnixListener
> {
466 self.0.duplicate().map(UnixListener
)
469 /// Returns the local socket address of this listener.
470 #[stable(feature = "unix_socket", since = "1.10.0")]
471 pub fn local_addr(&self) -> io
::Result
<SocketAddr
> {
472 SocketAddr
::new(|addr
, len
| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }
)
475 /// Moves the socket into or out of nonblocking mode.
476 #[stable(feature = "unix_socket", since = "1.10.0")]
477 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
478 self.0.set_nonblocking(nonblocking
)
481 /// Returns the value of the `SO_ERROR` option.
482 #[stable(feature = "unix_socket", since = "1.10.0")]
483 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
487 /// Returns an iterator over incoming connections.
489 /// The iterator will never return `None` and will also not yield the
490 /// peer's `SocketAddr` structure.
491 #[stable(feature = "unix_socket", since = "1.10.0")]
492 pub fn incoming
<'a
>(&'a
self) -> Incoming
<'a
> {
493 Incoming { listener: self }
497 #[stable(feature = "unix_socket", since = "1.10.0")]
498 impl AsRawFd
for UnixListener
{
499 fn as_raw_fd(&self) -> RawFd
{
504 #[stable(feature = "unix_socket", since = "1.10.0")]
505 impl FromRawFd
for UnixListener
{
506 unsafe fn from_raw_fd(fd
: RawFd
) -> UnixListener
{
507 UnixListener(Socket
::from_inner(fd
))
511 #[stable(feature = "unix_socket", since = "1.10.0")]
512 impl IntoRawFd
for UnixListener
{
513 fn into_raw_fd(self) -> RawFd
{
518 #[stable(feature = "unix_socket", since = "1.10.0")]
519 impl<'a
> IntoIterator
for &'a UnixListener
{
520 type Item
= io
::Result
<UnixStream
>;
521 type IntoIter
= Incoming
<'a
>;
523 fn into_iter(self) -> Incoming
<'a
> {
528 /// An iterator over incoming connections to a `UnixListener`.
530 /// It will never return `None`.
532 #[stable(feature = "unix_socket", since = "1.10.0")]
533 pub struct Incoming
<'a
> {
534 listener
: &'a UnixListener
,
537 #[stable(feature = "unix_socket", since = "1.10.0")]
538 impl<'a
> Iterator
for Incoming
<'a
> {
539 type Item
= io
::Result
<UnixStream
>;
541 fn next(&mut self) -> Option
<io
::Result
<UnixStream
>> {
542 Some(self.listener
.accept().map(|s
| s
.0))
545 fn size_hint(&self) -> (usize, Option
<usize>) {
546 (usize::max_value(), None
)
550 /// A Unix datagram socket.
555 /// use std::os::unix::net::UnixDatagram;
557 /// let socket = UnixDatagram::bind("/path/to/my/socket").unwrap();
558 /// socket.send_to(b"hello world", "/path/to/other/socket").unwrap();
559 /// let mut buf = [0; 100];
560 /// let (count, address) = socket.recv_from(&mut buf).unwrap();
561 /// println!("socket {:?} sent {:?}", address, &buf[..count]);
563 #[stable(feature = "unix_socket", since = "1.10.0")]
564 pub struct UnixDatagram(Socket
);
566 #[stable(feature = "unix_socket", since = "1.10.0")]
567 impl fmt
::Debug
for UnixDatagram
{
568 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
569 let mut builder
= fmt
.debug_struct("UnixDatagram");
570 builder
.field("fd", self.0.as_inner());
571 if let Ok(addr
) = self.local_addr() {
572 builder
.field("local", &addr
);
574 if let Ok(addr
) = self.peer_addr() {
575 builder
.field("peer", &addr
);
582 /// Creates a Unix datagram socket bound to the given path.
583 #[stable(feature = "unix_socket", since = "1.10.0")]
584 pub fn bind
<P
: AsRef
<Path
>>(path
: P
) -> io
::Result
<UnixDatagram
> {
585 fn inner(path
: &Path
) -> io
::Result
<UnixDatagram
> {
587 let socket
= UnixDatagram
::unbound()?
;
588 let (addr
, len
) = sockaddr_un(path
)?
;
590 cvt(libc
::bind(*socket
.0.as_inner(), &addr
as *const _
as *const _
, len
))?
;
598 /// Creates a Unix Datagram socket which is not bound to any address.
599 #[stable(feature = "unix_socket", since = "1.10.0")]
600 pub fn unbound() -> io
::Result
<UnixDatagram
> {
601 let inner
= Socket
::new_raw(libc
::AF_UNIX
, libc
::SOCK_DGRAM
)?
;
602 Ok(UnixDatagram(inner
))
605 /// Create an unnamed pair of connected sockets.
607 /// Returns two `UnixDatagrams`s which are connected to each other.
608 #[stable(feature = "unix_socket", since = "1.10.0")]
609 pub fn pair() -> io
::Result
<(UnixDatagram
, UnixDatagram
)> {
610 let (i1
, i2
) = Socket
::new_pair(libc
::AF_UNIX
, libc
::SOCK_DGRAM
)?
;
611 Ok((UnixDatagram(i1
), UnixDatagram(i2
)))
614 /// Connects the socket to the specified address.
616 /// The `send` method may be used to send data to the specified address.
617 /// `recv` and `recv_from` will only receive data from that address.
618 #[stable(feature = "unix_socket", since = "1.10.0")]
619 pub fn connect
<P
: AsRef
<Path
>>(&self, path
: P
) -> io
::Result
<()> {
620 fn inner(d
: &UnixDatagram
, path
: &Path
) -> io
::Result
<()> {
622 let (addr
, len
) = sockaddr_un(path
)?
;
624 cvt(libc
::connect(*d
.0.as_inner(), &addr
as *const _
as *const _
, len
))?
;
629 inner(self, path
.as_ref())
632 /// Creates a new independently owned handle to the underlying socket.
634 /// The returned `UnixListener` is a reference to the same socket that this
635 /// object references. Both handles can be used to accept incoming
636 /// connections and options set on one listener will affect the other.
637 #[stable(feature = "unix_socket", since = "1.10.0")]
638 pub fn try_clone(&self) -> io
::Result
<UnixDatagram
> {
639 self.0.duplicate().map(UnixDatagram
)
642 /// Returns the address of this socket.
643 #[stable(feature = "unix_socket", since = "1.10.0")]
644 pub fn local_addr(&self) -> io
::Result
<SocketAddr
> {
645 SocketAddr
::new(|addr
, len
| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) }
)
648 /// Returns the address of this socket's peer.
650 /// The `connect` method will connect the socket to a peer.
651 #[stable(feature = "unix_socket", since = "1.10.0")]
652 pub fn peer_addr(&self) -> io
::Result
<SocketAddr
> {
653 SocketAddr
::new(|addr
, len
| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) }
)
656 /// Receives data from the socket.
658 /// On success, returns the number of bytes read and the address from
659 /// whence the data came.
660 #[stable(feature = "unix_socket", since = "1.10.0")]
661 pub fn recv_from(&self, buf
: &mut [u8]) -> io
::Result
<(usize, SocketAddr
)> {
663 let addr
= SocketAddr
::new(|addr
, len
| {
665 count
= libc
::recvfrom(*self.0.as_inner(),
666 buf
.as_mut_ptr() as *mut _
,
673 } else if count
== 0 {
681 Ok((count
as usize, addr
))
684 /// Receives data from the socket.
686 /// On success, returns the number of bytes read.
687 #[stable(feature = "unix_socket", since = "1.10.0")]
688 pub fn recv(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
692 /// Sends data on the socket to the specified address.
694 /// On success, returns the number of bytes written.
695 #[stable(feature = "unix_socket", since = "1.10.0")]
696 pub fn send_to
<P
: AsRef
<Path
>>(&self, buf
: &[u8], path
: P
) -> io
::Result
<usize> {
697 fn inner(d
: &UnixDatagram
, buf
: &[u8], path
: &Path
) -> io
::Result
<usize> {
699 let (addr
, len
) = sockaddr_un(path
)?
;
701 let count
= cvt(libc
::sendto(*d
.0.as_inner(),
702 buf
.as_ptr() as *const _
,
705 &addr
as *const _
as *const _
,
710 inner(self, buf
, path
.as_ref())
713 /// Sends data on the socket to the socket's peer.
715 /// The peer address may be set by the `connect` method, and this method
716 /// will return an error if the socket has not already been connected.
718 /// On success, returns the number of bytes written.
719 #[stable(feature = "unix_socket", since = "1.10.0")]
720 pub fn send(&self, buf
: &[u8]) -> io
::Result
<usize> {
724 /// Sets the read timeout for the socket.
726 /// If the provided value is `None`, then `recv` and `recv_from` calls will
727 /// block indefinitely. It is an error to pass the zero `Duration` to this
729 #[stable(feature = "unix_socket", since = "1.10.0")]
730 pub fn set_read_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
731 self.0.set_timeout(timeout
, libc
::SO_RCVTIMEO
)
734 /// Sets the write timeout for the socket.
736 /// If the provided value is `None`, then `send` and `send_to` calls will
737 /// block indefinitely. It is an error to pass the zero `Duration` to this
739 #[stable(feature = "unix_socket", since = "1.10.0")]
740 pub fn set_write_timeout(&self, timeout
: Option
<Duration
>) -> io
::Result
<()> {
741 self.0.set_timeout(timeout
, libc
::SO_SNDTIMEO
)
744 /// Returns the read timeout of this socket.
745 #[stable(feature = "unix_socket", since = "1.10.0")]
746 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
747 self.0.timeout(libc
::SO_RCVTIMEO
)
750 /// Returns the write timeout of this socket.
751 #[stable(feature = "unix_socket", since = "1.10.0")]
752 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
753 self.0.timeout(libc
::SO_SNDTIMEO
)
756 /// Moves the socket into or out of nonblocking mode.
757 #[stable(feature = "unix_socket", since = "1.10.0")]
758 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
759 self.0.set_nonblocking(nonblocking
)
762 /// Returns the value of the `SO_ERROR` option.
763 #[stable(feature = "unix_socket", since = "1.10.0")]
764 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
768 /// Shut down the read, write, or both halves of this connection.
770 /// This function will cause all pending and future I/O calls on the
771 /// specified portions to immediately return with an appropriate value
772 /// (see the documentation of `Shutdown`).
773 #[stable(feature = "unix_socket", since = "1.10.0")]
774 pub fn shutdown(&self, how
: Shutdown
) -> io
::Result
<()> {
779 #[stable(feature = "unix_socket", since = "1.10.0")]
780 impl AsRawFd
for UnixDatagram
{
781 fn as_raw_fd(&self) -> RawFd
{
786 #[stable(feature = "unix_socket", since = "1.10.0")]
787 impl FromRawFd
for UnixDatagram
{
788 unsafe fn from_raw_fd(fd
: RawFd
) -> UnixDatagram
{
789 UnixDatagram(Socket
::from_inner(fd
))
793 #[stable(feature = "unix_socket", since = "1.10.0")]
794 impl IntoRawFd
for UnixDatagram
{
795 fn into_raw_fd(self) -> RawFd
{
800 #[cfg(all(test, not(target_os = "emscripten")))]
806 use sys_common
::io
::test
::tmpdir
;
810 macro_rules
! or_panic
{
814 Err(e
) => panic
!("{}", e
),
822 let socket_path
= dir
.path().join("sock");
824 let msg2
= b
"world!";
826 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
827 let thread
= thread
::spawn(move || {
828 let mut stream
= or_panic
!(listener
.accept()).0;
829 let mut buf
= [0; 5];
830 or_panic
!(stream
.read(&mut buf
));
831 assert_eq
!(&msg1
[..], &buf
[..]);
832 or_panic
!(stream
.write_all(msg2
));
835 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
836 assert_eq
!(Some(&*socket_path
),
837 stream
.peer_addr().unwrap().as_pathname());
838 or_panic
!(stream
.write_all(msg1
));
839 let mut buf
= vec
![];
840 or_panic
!(stream
.read_to_end(&mut buf
));
841 assert_eq
!(&msg2
[..], &buf
[..]);
844 thread
.join().unwrap();
850 let msg2
= b
"world!";
852 let (mut s1
, mut s2
) = or_panic
!(UnixStream
::pair());
853 let thread
= thread
::spawn(move || {
854 // s1 must be moved in or the test will hang!
855 let mut buf
= [0; 5];
856 or_panic
!(s1
.read(&mut buf
));
857 assert_eq
!(&msg1
[..], &buf
[..]);
858 or_panic
!(s1
.write_all(msg2
));
861 or_panic
!(s2
.write_all(msg1
));
862 let mut buf
= vec
![];
863 or_panic
!(s2
.read_to_end(&mut buf
));
864 assert_eq
!(&msg2
[..], &buf
[..]);
867 thread
.join().unwrap();
873 let socket_path
= dir
.path().join("sock");
877 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
878 let thread
= thread
::spawn(move || {
879 let mut stream
= or_panic
!(listener
.accept()).0;
880 or_panic
!(stream
.write_all(msg1
));
881 or_panic
!(stream
.write_all(msg2
));
884 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
885 let mut stream2
= or_panic
!(stream
.try_clone());
887 let mut buf
= [0; 5];
888 or_panic
!(stream
.read(&mut buf
));
889 assert_eq
!(&msg1
[..], &buf
[..]);
890 or_panic
!(stream2
.read(&mut buf
));
891 assert_eq
!(&msg2
[..], &buf
[..]);
893 thread
.join().unwrap();
899 let socket_path
= dir
.path().join("sock");
901 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
902 let thread
= thread
::spawn(move || {
903 for stream
in listener
.incoming().take(2) {
904 let mut stream
= or_panic
!(stream
);
906 or_panic
!(stream
.read(&mut buf
));
911 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
912 or_panic
!(stream
.write_all(&[0]));
915 thread
.join().unwrap();
921 let socket_path
= dir
.path()
922 .join("asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\
923 sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf");
924 match UnixStream
::connect(&socket_path
) {
925 Err(ref e
) if e
.kind() == io
::ErrorKind
::InvalidInput
=> {}
926 Err(e
) => panic
!("unexpected error {}", e
),
927 Ok(_
) => panic
!("unexpected success"),
930 match UnixListener
::bind(&socket_path
) {
931 Err(ref e
) if e
.kind() == io
::ErrorKind
::InvalidInput
=> {}
932 Err(e
) => panic
!("unexpected error {}", e
),
933 Ok(_
) => panic
!("unexpected success"),
936 match UnixDatagram
::bind(&socket_path
) {
937 Err(ref e
) if e
.kind() == io
::ErrorKind
::InvalidInput
=> {}
938 Err(e
) => panic
!("unexpected error {}", e
),
939 Ok(_
) => panic
!("unexpected success"),
946 let socket_path
= dir
.path().join("sock");
948 let _listener
= or_panic
!(UnixListener
::bind(&socket_path
));
950 let stream
= or_panic
!(UnixStream
::connect(&socket_path
));
951 let dur
= Duration
::new(15410, 0);
953 assert_eq
!(None
, or_panic
!(stream
.read_timeout()));
955 or_panic
!(stream
.set_read_timeout(Some(dur
)));
956 assert_eq
!(Some(dur
), or_panic
!(stream
.read_timeout()));
958 assert_eq
!(None
, or_panic
!(stream
.write_timeout()));
960 or_panic
!(stream
.set_write_timeout(Some(dur
)));
961 assert_eq
!(Some(dur
), or_panic
!(stream
.write_timeout()));
963 or_panic
!(stream
.set_read_timeout(None
));
964 assert_eq
!(None
, or_panic
!(stream
.read_timeout()));
966 or_panic
!(stream
.set_write_timeout(None
));
967 assert_eq
!(None
, or_panic
!(stream
.write_timeout()));
971 fn test_read_timeout() {
973 let socket_path
= dir
.path().join("sock");
975 let _listener
= or_panic
!(UnixListener
::bind(&socket_path
));
977 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
978 or_panic
!(stream
.set_read_timeout(Some(Duration
::from_millis(1000))));
980 let mut buf
= [0; 10];
981 let kind
= stream
.read(&mut buf
).err().expect("expected error").kind();
982 assert
!(kind
== io
::ErrorKind
::WouldBlock
|| kind
== io
::ErrorKind
::TimedOut
);
986 fn test_read_with_timeout() {
988 let socket_path
= dir
.path().join("sock");
990 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
992 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
993 or_panic
!(stream
.set_read_timeout(Some(Duration
::from_millis(1000))));
995 let mut other_end
= or_panic
!(listener
.accept()).0;
996 or_panic
!(other_end
.write_all(b
"hello world"));
998 let mut buf
= [0; 11];
999 or_panic
!(stream
.read(&mut buf
));
1000 assert_eq
!(b
"hello world", &buf
[..]);
1002 let kind
= stream
.read(&mut buf
).err().expect("expected error").kind();
1003 assert
!(kind
== io
::ErrorKind
::WouldBlock
|| kind
== io
::ErrorKind
::TimedOut
);
1007 fn test_unix_datagram() {
1009 let path1
= dir
.path().join("sock1");
1010 let path2
= dir
.path().join("sock2");
1012 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
1013 let sock2
= or_panic
!(UnixDatagram
::bind(&path2
));
1015 let msg
= b
"hello world";
1016 or_panic
!(sock1
.send_to(msg
, &path2
));
1017 let mut buf
= [0; 11];
1018 or_panic
!(sock2
.recv_from(&mut buf
));
1019 assert_eq
!(msg
, &buf
[..]);
1023 fn test_unnamed_unix_datagram() {
1025 let path1
= dir
.path().join("sock1");
1027 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
1028 let sock2
= or_panic
!(UnixDatagram
::unbound());
1030 let msg
= b
"hello world";
1031 or_panic
!(sock2
.send_to(msg
, &path1
));
1032 let mut buf
= [0; 11];
1033 let (usize, addr
) = or_panic
!(sock1
.recv_from(&mut buf
));
1034 assert_eq
!(usize, 11);
1035 assert
!(addr
.is_unnamed());
1036 assert_eq
!(msg
, &buf
[..]);
1040 fn test_connect_unix_datagram() {
1042 let path1
= dir
.path().join("sock1");
1043 let path2
= dir
.path().join("sock2");
1045 let bsock1
= or_panic
!(UnixDatagram
::bind(&path1
));
1046 let bsock2
= or_panic
!(UnixDatagram
::bind(&path2
));
1047 let sock
= or_panic
!(UnixDatagram
::unbound());
1048 or_panic
!(sock
.connect(&path1
));
1051 let msg
= b
"hello there";
1052 or_panic
!(sock
.send(msg
));
1053 let mut buf
= [0; 11];
1054 let (usize, addr
) = or_panic
!(bsock1
.recv_from(&mut buf
));
1055 assert_eq
!(usize, 11);
1056 assert
!(addr
.is_unnamed());
1057 assert_eq
!(msg
, &buf
[..]);
1059 // Changing default socket works too
1060 or_panic
!(sock
.connect(&path2
));
1061 or_panic
!(sock
.send(msg
));
1062 or_panic
!(bsock2
.recv_from(&mut buf
));
1066 fn test_unix_datagram_recv() {
1068 let path1
= dir
.path().join("sock1");
1070 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
1071 let sock2
= or_panic
!(UnixDatagram
::unbound());
1072 or_panic
!(sock2
.connect(&path1
));
1074 let msg
= b
"hello world";
1075 or_panic
!(sock2
.send(msg
));
1076 let mut buf
= [0; 11];
1077 let size
= or_panic
!(sock1
.recv(&mut buf
));
1078 assert_eq
!(size
, 11);
1079 assert_eq
!(msg
, &buf
[..]);
1083 fn datagram_pair() {
1084 let msg1
= b
"hello";
1085 let msg2
= b
"world!";
1087 let (s1
, s2
) = or_panic
!(UnixDatagram
::pair());
1088 let thread
= thread
::spawn(move || {
1089 // s1 must be moved in or the test will hang!
1090 let mut buf
= [0; 5];
1091 or_panic
!(s1
.recv(&mut buf
));
1092 assert_eq
!(&msg1
[..], &buf
[..]);
1093 or_panic
!(s1
.send(msg2
));
1096 or_panic
!(s2
.send(msg1
));
1097 let mut buf
= [0; 6];
1098 or_panic
!(s2
.recv(&mut buf
));
1099 assert_eq
!(&msg2
[..], &buf
[..]);
1102 thread
.join().unwrap();
1106 fn abstract_namespace_not_allowed() {
1107 assert
!(UnixStream
::connect("\0asdf").is_err());