unix_socket/
lib.rs

1//! Support for Unix domain socket clients and servers.
2#![warn(missing_docs)]
3#![doc(html_root_url="https://doc.rust-lang.org/unix-socket/doc/v0.5.0")]
4
5#[macro_use]
6extern crate cfg_if;
7extern crate libc;
8
9use std::ascii;
10use std::cmp::Ordering;
11use std::convert::AsRef;
12use std::ffi::OsStr;
13use std::fmt;
14use std::io;
15use std::iter::IntoIterator;
16use std::mem;
17use std::mem::size_of;
18use std::net::Shutdown;
19use std::os::unix::ffi::OsStrExt;
20use std::os::unix::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd};
21use std::path::Path;
22use std::time::Duration;
23
24fn sun_path_offset() -> usize {
25    unsafe {
26        // Work with an actual instance of the type since using a null pointer is UB
27        let addr: libc::sockaddr_un = mem::uninitialized();
28        let base = &addr as *const _ as usize;
29        let path = &addr.sun_path as *const _ as usize;
30        path - base
31    }
32}
33
34fn cvt(v: libc::c_int) -> io::Result<libc::c_int> {
35    if v < 0 {
36        Err(io::Error::last_os_error())
37    } else {
38        Ok(v)
39    }
40}
41
42fn cvt_s(v: libc::ssize_t) -> io::Result<libc::ssize_t> {
43    if v < 0 {
44        Err(io::Error::last_os_error())
45    } else {
46        Ok(v)
47    }
48}
49
50struct Inner(RawFd);
51
52impl Drop for Inner {
53    fn drop(&mut self) {
54        unsafe {
55            libc::close(self.0);
56        }
57    }
58}
59
60impl Inner {
61    fn new(kind: libc::c_int) -> io::Result<Inner> {
62        unsafe { cvt(libc::socket(libc::AF_UNIX, kind, 0)).map(Inner) }
63    }
64
65    fn new_pair(kind: libc::c_int) -> io::Result<(Inner, Inner)> {
66        unsafe {
67            let mut fds = [0, 0];
68            try!(cvt(libc::socketpair(libc::AF_UNIX, kind, 0, fds.as_mut_ptr())));
69            Ok((Inner(fds[0]), Inner(fds[1])))
70        }
71    }
72
73    fn try_clone(&self) -> io::Result<Inner> {
74        unsafe { cvt(libc::dup(self.0)).map(Inner) }
75    }
76
77    fn shutdown(&self, how: Shutdown) -> io::Result<()> {
78        let how = match how {
79            Shutdown::Read => libc::SHUT_RD,
80            Shutdown::Write => libc::SHUT_WR,
81            Shutdown::Both => libc::SHUT_RDWR,
82        };
83
84        unsafe { cvt(libc::shutdown(self.0, how)).map(|_| ()) }
85    }
86
87    fn timeout(&self, kind: libc::c_int) -> io::Result<Option<Duration>> {
88        let timeout = unsafe {
89            let mut timeout: libc::timeval = mem::zeroed();
90            let mut size = mem::size_of::<libc::timeval>() as libc::socklen_t;
91            try!(cvt(libc::getsockopt(self.0,
92                                      libc::SOL_SOCKET,
93                                      kind,
94                                      &mut timeout as *mut _ as *mut _,
95                                      &mut size as *mut _ as *mut _)));
96            timeout
97        };
98
99        if timeout.tv_sec == 0 && timeout.tv_usec == 0 {
100            Ok(None)
101        } else {
102            Ok(Some(Duration::new(timeout.tv_sec as u64, (timeout.tv_usec as u32) * 1000)))
103        }
104    }
105
106    fn set_timeout(&self, dur: Option<Duration>, kind: libc::c_int) -> io::Result<()> {
107        let timeout = match dur {
108            Some(dur) => {
109                if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
110                    return Err(io::Error::new(io::ErrorKind::InvalidInput,
111                                              "cannot set a 0 duration timeout"));
112                }
113
114                let (secs, usecs) = if dur.as_secs() > libc::time_t::max_value() as u64 {
115                    (libc::time_t::max_value(), 999_999)
116                } else {
117                    (dur.as_secs() as libc::time_t,
118                     (dur.subsec_nanos() / 1000) as libc::suseconds_t)
119                };
120                let mut timeout = libc::timeval {
121                    tv_sec: secs,
122                    tv_usec: usecs,
123                };
124                if timeout.tv_sec == 0 && timeout.tv_usec == 0 {
125                    timeout.tv_usec = 1;
126                }
127                timeout
128            }
129            None => {
130                libc::timeval {
131                    tv_sec: 0,
132                    tv_usec: 0,
133                }
134            }
135        };
136
137        unsafe {
138            cvt(libc::setsockopt(self.0,
139                                 libc::SOL_SOCKET,
140                                 kind,
141                                 &timeout as *const _ as *const _,
142                                 mem::size_of::<libc::timeval>() as libc::socklen_t))
143                .map(|_| ())
144        }
145    }
146
147    fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
148        let mut nonblocking = nonblocking as libc::c_ulong;
149        unsafe { cvt(libc::ioctl(self.0, libc::FIONBIO, &mut nonblocking)).map(|_| ()) }
150    }
151
152    fn take_error(&self) -> io::Result<Option<io::Error>> {
153        let mut errno: libc::c_int = 0;
154
155        unsafe {
156            try!(cvt(libc::getsockopt(self.0,
157                                      libc::SOL_SOCKET,
158                                      libc::SO_ERROR,
159                                      &mut errno as *mut _ as *mut _,
160                                      &mut mem::size_of_val(&errno) as *mut _ as *mut _)));
161        }
162
163        if errno == 0 {
164            Ok(None)
165        } else {
166            Ok(Some(io::Error::from_raw_os_error(errno)))
167        }
168    }
169}
170
171unsafe fn sockaddr_un<P: AsRef<Path>>(path: P) -> io::Result<(libc::sockaddr_un, libc::socklen_t)> {
172    let mut addr: libc::sockaddr_un = mem::zeroed();
173    addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
174
175    let bytes = path.as_ref().as_os_str().as_bytes();
176
177    match (bytes.get(0), bytes.len().cmp(&addr.sun_path.len())) {
178        // Abstract paths don't need a null terminator
179        (Some(&0), Ordering::Greater) => {
180            return Err(io::Error::new(io::ErrorKind::InvalidInput,
181                                      "path must be no longer than SUN_LEN"));
182        }
183        (_, Ordering::Greater) | (_, Ordering::Equal) => {
184            return Err(io::Error::new(io::ErrorKind::InvalidInput,
185                                      "path must be shorter than SUN_LEN"));
186        }
187        _ => {}
188    }
189    for (dst, src) in addr.sun_path.iter_mut().zip(bytes.iter()) {
190        *dst = *src as libc::c_char;
191    }
192    // null byte for pathname addresses is already there because we zeroed the
193    // struct
194
195    let mut len = sun_path_offset() + bytes.len();
196    match bytes.get(0) {
197        Some(&0) | None => {}
198        Some(_) => len += 1,
199    }
200    Ok((addr, len as libc::socklen_t))
201}
202
203enum AddressKind<'a> {
204    Unnamed,
205    Pathname(&'a Path),
206    Abstract(&'a [u8]),
207}
208
209/// An address associated with a Unix socket.
210#[derive(Clone)]
211pub struct SocketAddr {
212    addr: libc::sockaddr_un,
213    len: libc::socklen_t,
214}
215
216impl SocketAddr {
217    fn new<F>(f: F) -> io::Result<SocketAddr>
218        where F: FnOnce(*mut libc::sockaddr, *mut libc::socklen_t) -> libc::c_int
219    {
220        unsafe {
221            let mut addr: libc::sockaddr_un = mem::zeroed();
222            let mut len = mem::size_of::<libc::sockaddr_un>() as libc::socklen_t;
223            try!(cvt(f(&mut addr as *mut _ as *mut _, &mut len)));
224
225            if len == 0 {
226                // When there is a datagram from unnamed unix socket
227                // linux returns zero bytes of address
228                len = sun_path_offset() as libc::socklen_t;  // i.e. zero-length address
229            } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
230                return Err(io::Error::new(io::ErrorKind::InvalidInput,
231                                          "file descriptor did not correspond to a Unix socket"));
232            }
233
234            Ok(SocketAddr {
235                addr: addr,
236                len: len,
237            })
238        }
239    }
240
241    /// Returns true iff the address is unnamed.
242    pub fn is_unnamed(&self) -> bool {
243        if let AddressKind::Unnamed = self.address() {
244            true
245        } else {
246            false
247        }
248    }
249
250    /// Returns the contents of this address if it is a `pathname` address.
251    pub fn as_pathname(&self) -> Option<&Path> {
252        if let AddressKind::Pathname(path) = self.address() {
253            Some(path)
254        } else {
255            None
256        }
257    }
258
259    fn address<'a>(&'a self) -> AddressKind<'a> {
260        let len = self.len as usize - sun_path_offset();
261        let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
262
263        // OSX seems to return a len of 16 and a zeroed sun_path for unnamed addresses
264        if len == 0 || (cfg!(not(target_os = "linux")) && self.addr.sun_path[0] == 0) {
265            AddressKind::Unnamed
266        } else if self.addr.sun_path[0] == 0 {
267            AddressKind::Abstract(&path[1..len])
268        } else {
269            AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref())
270        }
271    }
272}
273
274impl fmt::Debug for SocketAddr {
275    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
276        match self.address() {
277            AddressKind::Unnamed => write!(fmt, "(unnamed)"),
278            AddressKind::Abstract(name) => write!(fmt, "{} (abstract)", AsciiEscaped(name)),
279            AddressKind::Pathname(path) => write!(fmt, "{:?} (pathname)", path),
280        }
281    }
282}
283
284struct AsciiEscaped<'a>(&'a [u8]);
285
286impl<'a> fmt::Display for AsciiEscaped<'a> {
287    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
288        try!(write!(fmt, "\""));
289        for byte in self.0.iter().cloned().flat_map(ascii::escape_default) {
290            try!(write!(fmt, "{}", byte as char));
291        }
292        write!(fmt, "\"")
293    }
294}
295
296/// OS specific extension traits.
297pub mod os {
298    /// Linux specific extension traits.
299    #[cfg(target_os = "linux")]
300    pub mod linux {
301        use {AddressKind, SocketAddr};
302
303        /// Linux specific extensions for the `SocketAddr` type.
304        pub trait SocketAddrExt {
305            /// Returns the contents of this address (without the leading
306            /// null byte) if it is an `abstract` address.
307            fn as_abstract(&self) -> Option<&[u8]>;
308        }
309
310        impl SocketAddrExt for SocketAddr {
311            fn as_abstract(&self) -> Option<&[u8]> {
312                if let AddressKind::Abstract(path) = self.address() {
313                    Some(path)
314                } else {
315                    None
316                }
317            }
318        }
319    }
320}
321
322/// A Unix stream socket.
323///
324/// # Examples
325///
326/// ```rust,no_run
327/// use unix_socket::UnixStream;
328/// use std::io::prelude::*;
329///
330/// let mut stream = UnixStream::connect("/path/to/my/socket").unwrap();
331/// stream.write_all(b"hello world").unwrap();
332/// let mut response = String::new();
333/// stream.read_to_string(&mut response).unwrap();
334/// println!("{}", response);
335/// ```
336pub struct UnixStream {
337    inner: Inner,
338}
339
340impl fmt::Debug for UnixStream {
341    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
342        let mut builder = fmt.debug_struct("UnixStream");
343        builder.field("fd", &self.inner.0);
344        if let Ok(addr) = self.local_addr() {
345            builder.field("local", &addr);
346        }
347        if let Ok(addr) = self.peer_addr() {
348            builder.field("peer", &addr);
349        }
350        builder.finish()
351    }
352}
353
354impl UnixStream {
355    /// Connects to the socket named by `path`.
356    ///
357    /// Linux provides, as a nonportable extension, a separate "abstract"
358    /// address namespace as opposed to filesystem-based addressing. If `path`
359    /// begins with a null byte, it will be interpreted as an "abstract"
360    /// address. Otherwise, it will be interpreted as a "pathname" address,
361    /// corresponding to a path on the filesystem.
362    pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
363        unsafe {
364            let inner = try!(Inner::new(libc::SOCK_STREAM));
365            let (addr, len) = try!(sockaddr_un(path));
366
367            let ret = libc::connect(inner.0, &addr as *const _ as *const _, len);
368            if ret < 0 {
369                Err(io::Error::last_os_error())
370            } else {
371                Ok(UnixStream { inner: inner })
372            }
373        }
374    }
375
376    /// Creates an unnamed pair of connected sockets.
377    ///
378    /// Returns two `UnixStream`s which are connected to each other.
379    pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
380        let (i1, i2) = try!(Inner::new_pair(libc::SOCK_STREAM));
381        Ok((UnixStream { inner: i1 }, UnixStream { inner: i2 }))
382    }
383
384    /// Creates a new independently owned handle to the underlying socket.
385    ///
386    /// The returned `UnixStream` is a reference to the same stream that this
387    /// object references. Both handles will read and write the same stream of
388    /// data, and options set on one stream will be propogated to the other
389    /// stream.
390    pub fn try_clone(&self) -> io::Result<UnixStream> {
391        Ok(UnixStream { inner: try!(self.inner.try_clone()) })
392    }
393
394    /// Returns the socket address of the local half of this connection.
395    pub fn local_addr(&self) -> io::Result<SocketAddr> {
396        SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.inner.0, addr, len) })
397    }
398
399    /// Returns the socket address of the remote half of this connection.
400    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
401        SocketAddr::new(|addr, len| unsafe { libc::getpeername(self.inner.0, addr, len) })
402    }
403
404    /// Sets the read timeout for the socket.
405    ///
406    /// If the provided value is `None`, then `read` calls will block
407    /// indefinitely. It is an error to pass the zero `Duration` to this
408    /// method.
409    pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
410        self.inner.set_timeout(timeout, libc::SO_RCVTIMEO)
411    }
412
413    /// Sets the write timeout for the socket.
414    ///
415    /// If the provided value is `None`, then `write` calls will block
416    /// indefinitely. It is an error to pass the zero `Duration` to this
417    /// method.
418    pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
419        self.inner.set_timeout(timeout, libc::SO_SNDTIMEO)
420    }
421
422    /// Returns the read timeout of this socket.
423    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
424        self.inner.timeout(libc::SO_RCVTIMEO)
425    }
426
427    /// Returns the write timeout of this socket.
428    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
429        self.inner.timeout(libc::SO_SNDTIMEO)
430    }
431
432    /// Moves the socket into or out of nonblocking mode.
433    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
434        self.inner.set_nonblocking(nonblocking)
435    }
436
437    /// Returns the value of the `SO_ERROR` option.
438    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
439        self.inner.take_error()
440    }
441
442    /// Shuts down the read, write, or both halves of this connection.
443    ///
444    /// This function will cause all pending and future I/O calls on the
445    /// specified portions to immediately return with an appropriate value
446    /// (see the documentation of `Shutdown`).
447    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
448        self.inner.shutdown(how)
449    }
450}
451
452impl io::Read for UnixStream {
453    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
454        io::Read::read(&mut &*self, buf)
455    }
456}
457
458impl<'a> io::Read for &'a UnixStream {
459    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
460        unsafe {
461            cvt_s(libc::recv(self.inner.0, buf.as_mut_ptr() as *mut _, buf.len(), 0))
462                .map(|r| r as usize)
463        }
464    }
465}
466
467impl io::Write for UnixStream {
468    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
469        io::Write::write(&mut &*self, buf)
470    }
471
472    fn flush(&mut self) -> io::Result<()> {
473        io::Write::flush(&mut &*self)
474    }
475}
476
477impl<'a> io::Write for &'a UnixStream {
478    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
479        unsafe {
480            cvt_s(libc::send(self.inner.0, buf.as_ptr() as *const _, buf.len(), 0))
481                .map(|r| r as usize)
482        }
483    }
484
485    fn flush(&mut self) -> io::Result<()> {
486        Ok(())
487    }
488}
489
490impl AsRawFd for UnixStream {
491    fn as_raw_fd(&self) -> RawFd {
492        self.inner.0
493    }
494}
495
496impl FromRawFd for UnixStream {
497    unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
498        UnixStream { inner: Inner(fd) }
499    }
500}
501
502impl IntoRawFd for UnixStream {
503    fn into_raw_fd(self) -> RawFd {
504        let fd = self.inner.0;
505        mem::forget(self);
506        fd
507    }
508}
509
510/// A structure representing a Unix domain socket server.
511///
512/// # Examples
513///
514/// ```rust,no_run
515/// use std::thread;
516/// use unix_socket::{UnixStream, UnixListener};
517///
518/// fn handle_client(stream: UnixStream) {
519///     // ...
520/// }
521///
522/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
523///
524/// // accept connections and process them, spawning a new thread for each one
525/// for stream in listener.incoming() {
526///     match stream {
527///         Ok(stream) => {
528///             /* connection succeeded */
529///             thread::spawn(|| handle_client(stream));
530///         }
531///         Err(err) => {
532///             /* connection failed */
533///             break;
534///         }
535///     }
536/// }
537///
538/// // close the listener socket
539/// drop(listener);
540/// ```
541pub struct UnixListener {
542    inner: Inner,
543}
544
545impl fmt::Debug for UnixListener {
546    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
547        let mut builder = fmt.debug_struct("UnixListener");
548        builder.field("fd", &self.inner.0);
549        if let Ok(addr) = self.local_addr() {
550            builder.field("local", &addr);
551        }
552        builder.finish()
553    }
554}
555
556impl UnixListener {
557    /// Creates a new `UnixListener` bound to the specified socket.
558    ///
559    /// Linux provides, as a nonportable extension, a separate "abstract"
560    /// address namespace as opposed to filesystem-based addressing. If `path`
561    /// begins with a null byte, it will be interpreted as an "abstract"
562    /// address. Otherwise, it will be interpreted as a "pathname" address,
563    /// corresponding to a path on the filesystem.
564    pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
565        unsafe {
566            let inner = try!(Inner::new(libc::SOCK_STREAM));
567            let (addr, len) = try!(sockaddr_un(path));
568
569            try!(cvt(libc::bind(inner.0, &addr as *const _ as *const _, len)));
570            try!(cvt(libc::listen(inner.0, 128)));
571
572            Ok(UnixListener { inner: inner })
573        }
574    }
575
576    /// Accepts a new incoming connection to this listener.
577    ///
578    /// This function will block the calling thread until a new Unix connection
579    /// is established. When established, the corersponding `UnixStream` and
580    /// the remote peer's address will be returned.
581    pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
582        unsafe {
583            let mut fd = 0;
584            let addr = try!(SocketAddr::new(|addr, len| {
585                fd = libc::accept(self.inner.0, addr, len);
586                fd
587            }));
588
589            Ok((UnixStream { inner: Inner(fd) }, addr))
590        }
591    }
592
593    /// Creates a new independently owned handle to the underlying socket.
594    ///
595    /// The returned `UnixListener` is a reference to the same socket that this
596    /// object references. Both handles can be used to accept incoming
597    /// connections and options set on one listener will affect the other.
598    pub fn try_clone(&self) -> io::Result<UnixListener> {
599        Ok(UnixListener { inner: try!(self.inner.try_clone()) })
600    }
601
602    /// Returns the local socket address of this listener.
603    pub fn local_addr(&self) -> io::Result<SocketAddr> {
604        SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.inner.0, addr, len) })
605    }
606
607    /// Moves the socket into or out of nonblocking mode.
608    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
609        self.inner.set_nonblocking(nonblocking)
610    }
611
612    /// Returns the value of the `SO_ERROR` option.
613    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
614        self.inner.take_error()
615    }
616
617    /// Returns an iterator over incoming connections.
618    ///
619    /// The iterator will never return `None` and will also not yield the
620    /// peer's `SocketAddr` structure.
621    pub fn incoming<'a>(&'a self) -> Incoming<'a> {
622        Incoming { listener: self }
623    }
624}
625
626impl AsRawFd for UnixListener {
627    fn as_raw_fd(&self) -> RawFd {
628        self.inner.0
629    }
630}
631
632impl FromRawFd for UnixListener {
633    unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
634        UnixListener { inner: Inner(fd) }
635    }
636}
637
638impl IntoRawFd for UnixListener {
639    fn into_raw_fd(self) -> RawFd {
640        let fd = self.inner.0;
641        mem::forget(self);
642        fd
643    }
644}
645
646impl<'a> IntoIterator for &'a UnixListener {
647    type Item = io::Result<UnixStream>;
648    type IntoIter = Incoming<'a>;
649
650    fn into_iter(self) -> Incoming<'a> {
651        self.incoming()
652    }
653}
654
655/// An iterator over incoming connections to a `UnixListener`.
656///
657/// It will never return `None`.
658#[derive(Debug)]
659pub struct Incoming<'a> {
660    listener: &'a UnixListener,
661}
662
663impl<'a> Iterator for Incoming<'a> {
664    type Item = io::Result<UnixStream>;
665
666    fn next(&mut self) -> Option<io::Result<UnixStream>> {
667        Some(self.listener.accept().map(|s| s.0))
668    }
669
670    fn size_hint(&self) -> (usize, Option<usize>) {
671        (usize::max_value(), None)
672    }
673}
674
675/// A Unix datagram socket.
676///
677/// # Examples
678///
679/// ```rust,no_run
680/// use unix_socket::UnixDatagram;
681///
682/// let socket = UnixDatagram::bind("/path/to/my/socket").unwrap();
683/// socket.send_to(b"hello world", "/path/to/other/socket").unwrap();
684/// let mut buf = [0; 100];
685/// let (count, address) = socket.recv_from(&mut buf).unwrap();
686/// println!("socket {:?} sent {:?}", address, &buf[..count]);
687/// ```
688pub struct UnixDatagram {
689    inner: Inner,
690}
691
692impl fmt::Debug for UnixDatagram {
693    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
694        let mut builder = fmt.debug_struct("UnixDatagram");
695        builder.field("fd", &self.inner.0);
696        if let Ok(addr) = self.local_addr() {
697            builder.field("local", &addr);
698        }
699        if let Ok(addr) = self.peer_addr() {
700            builder.field("peer", &addr);
701        }
702        builder.finish()
703    }
704}
705
706impl UnixDatagram {
707    /// Creates a Unix datagram socket bound to the given path.
708    ///
709    /// Linux provides, as a nonportable extension, a separate "abstract"
710    /// address namespace as opposed to filesystem-based addressing. If `path`
711    /// begins with a null byte, it will be interpreted as an "abstract"
712    /// address. Otherwise, it will be interpreted as a "pathname" address,
713    /// corresponding to a path on the filesystem.
714    pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
715        unsafe {
716            let inner = try!(Inner::new(libc::SOCK_DGRAM));
717            let (addr, len) = try!(sockaddr_un(path));
718
719            try!(cvt(libc::bind(inner.0, &addr as *const _ as *const _, len)));
720
721            Ok(UnixDatagram { inner: inner })
722        }
723    }
724
725    /// Creates a Unix Datagram socket which is not bound to any address.
726    pub fn unbound() -> io::Result<UnixDatagram> {
727        let inner = try!(Inner::new(libc::SOCK_DGRAM));
728        Ok(UnixDatagram { inner: inner })
729    }
730
731    /// Create an unnamed pair of connected sockets.
732    ///
733    /// Returns two `UnixDatagrams`s which are connected to each other.
734    pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
735        let (i1, i2) = try!(Inner::new_pair(libc::SOCK_DGRAM));
736        Ok((UnixDatagram { inner: i1 }, UnixDatagram { inner: i2 }))
737    }
738
739    /// Connects the socket to the specified address.
740    ///
741    /// The `send` method may be used to send data to the specified address.
742    /// `recv` and `recv_from` will only receive data from that address.
743    pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
744        unsafe {
745            let (addr, len) = try!(sockaddr_un(path));
746
747            try!(cvt(libc::connect(self.inner.0, &addr as *const _ as *const _, len)));
748
749            Ok(())
750        }
751    }
752
753    /// Returns the address of this socket.
754    pub fn local_addr(&self) -> io::Result<SocketAddr> {
755        SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.inner.0, addr, len) })
756    }
757
758    /// Returns the address of this socket's peer.
759    ///
760    /// The `connect` method will connect the socket to a peer.
761    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
762        SocketAddr::new(|addr, len| unsafe { libc::getpeername(self.inner.0, addr, len) })
763    }
764
765    /// Receives data from the socket.
766    ///
767    /// On success, returns the number of bytes read and the address from
768    /// whence the data came.
769    pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
770        let mut count = 0;
771        let addr = try!(SocketAddr::new(|addr, len| {
772            unsafe {
773                count = libc::recvfrom(self.inner.0,
774                                       buf.as_mut_ptr() as *mut _,
775                                       buf.len(),
776                                       0,
777                                       addr,
778                                       len);
779                if count > 0 {
780                    1
781                } else if count == 0 {
782                    0
783                } else {
784                    -1
785                }
786            }
787        }));
788
789        Ok((count as usize, addr))
790    }
791
792    /// Receives data from the socket.
793    ///
794    /// On success, returns the number of bytes read.
795    pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
796        unsafe {
797            let count = try!(cvt_s(libc::recv(self.inner.0,
798                                              buf.as_mut_ptr() as *mut _,
799                                              buf.len(),
800                                              0)));
801            Ok(count as usize)
802        }
803    }
804
805    /// Sends data on the socket to the specified address.
806    ///
807    /// On success, returns the number of bytes written.
808    pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
809        unsafe {
810            let (addr, len) = try!(sockaddr_un(path));
811
812            let count = try!(cvt_s(libc::sendto(self.inner.0,
813                                                buf.as_ptr() as *const _,
814                                                buf.len(),
815                                                0,
816                                                &addr as *const _ as *const _,
817                                                len)));
818            Ok(count as usize)
819        }
820    }
821
822    /// Sends data on the socket to the socket's peer.
823    ///
824    /// The peer address may be set by the `connect` method, and this method
825    /// will return an error if the socket has not already been connected.
826    ///
827    /// On success, returns the number of bytes written.
828    pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
829        unsafe {
830            let count = try!(cvt_s(libc::send(self.inner.0,
831                                              buf.as_ptr() as *const _,
832                                              buf.len(),
833                                              0)));
834            Ok(count as usize)
835        }
836    }
837
838    /// Sets the read timeout for the socket.
839    ///
840    /// If the provided value is `None`, then `recv` and `recv_from` calls will
841    /// block indefinitely. It is an error to pass the zero `Duration` to this
842    /// method.
843    pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
844        self.inner.set_timeout(timeout, libc::SO_RCVTIMEO)
845    }
846
847    /// Sets the write timeout for the socket.
848    ///
849    /// If the provided value is `None`, then `send` and `send_to` calls will
850    /// block indefinitely. It is an error to pass the zero `Duration` to this
851    /// method.
852    pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
853        self.inner.set_timeout(timeout, libc::SO_SNDTIMEO)
854    }
855
856    /// Returns the read timeout of this socket.
857    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
858        self.inner.timeout(libc::SO_RCVTIMEO)
859    }
860
861    /// Returns the write timeout of this socket.
862    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
863        self.inner.timeout(libc::SO_SNDTIMEO)
864    }
865
866    /// Moves the socket into or out of nonblocking mode.
867    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
868        self.inner.set_nonblocking(nonblocking)
869    }
870
871    /// Returns the value of the `SO_ERROR` option.
872    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
873        self.inner.take_error()
874    }
875
876    /// Shut down the read, write, or both halves of this connection.
877    ///
878    /// This function will cause all pending and future I/O calls on the
879    /// specified portions to immediately return with an appropriate value
880    /// (see the documentation of `Shutdown`).
881    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
882        self.inner.shutdown(how)
883    }
884}
885
886impl AsRawFd for UnixDatagram {
887    fn as_raw_fd(&self) -> RawFd {
888        self.inner.0
889    }
890}
891
892impl FromRawFd for UnixDatagram {
893    unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
894        UnixDatagram { inner: Inner(fd) }
895    }
896}
897
898impl IntoRawFd for UnixDatagram {
899    fn into_raw_fd(self) -> RawFd {
900        let fd = self.inner.0;
901        mem::forget(self);
902        fd
903    }
904}
905
906#[cfg(test)]
907mod test {
908    extern crate tempdir;
909
910    use std::thread;
911    use std::io;
912    use std::io::prelude::*;
913    use std::time::Duration;
914    use self::tempdir::TempDir;
915
916    use super::*;
917
918    macro_rules! or_panic {
919        ($e:expr) => {
920            match $e {
921                Ok(e) => e,
922                Err(e) => panic!("{}", e),
923            }
924        }
925    }
926
927    #[test]
928    fn basic() {
929        let dir = or_panic!(TempDir::new("unix_socket"));
930        let socket_path = dir.path().join("sock");
931        let msg1 = b"hello";
932        let msg2 = b"world!";
933
934        let listener = or_panic!(UnixListener::bind(&socket_path));
935        let thread = thread::spawn(move || {
936            let mut stream = or_panic!(listener.accept()).0;
937            let mut buf = [0; 5];
938            or_panic!(stream.read(&mut buf));
939            assert_eq!(&msg1[..], &buf[..]);
940            or_panic!(stream.write_all(msg2));
941        });
942
943        let mut stream = or_panic!(UnixStream::connect(&socket_path));
944        assert_eq!(Some(&*socket_path),
945                   stream.peer_addr().unwrap().as_pathname());
946        or_panic!(stream.write_all(msg1));
947        let mut buf = vec![];
948        or_panic!(stream.read_to_end(&mut buf));
949        assert_eq!(&msg2[..], &buf[..]);
950        drop(stream);
951
952        thread.join().unwrap();
953    }
954
955    #[test]
956    fn pair() {
957        let msg1 = b"hello";
958        let msg2 = b"world!";
959
960        let (mut s1, mut s2) = or_panic!(UnixStream::pair());
961        let thread = thread::spawn(move || {
962            // s1 must be moved in or the test will hang!
963            let mut buf = [0; 5];
964            or_panic!(s1.read(&mut buf));
965            assert_eq!(&msg1[..], &buf[..]);
966            or_panic!(s1.write_all(msg2));
967        });
968
969        or_panic!(s2.write_all(msg1));
970        let mut buf = vec![];
971        or_panic!(s2.read_to_end(&mut buf));
972        assert_eq!(&msg2[..], &buf[..]);
973        drop(s2);
974
975        thread.join().unwrap();
976    }
977
978    #[test]
979    #[cfg(target_os = "linux")]
980    fn abstract_address() {
981        use os::linux::SocketAddrExt;
982
983        let socket_path = "\0the path";
984        let msg1 = b"hello";
985        let msg2 = b"world!";
986
987        let listener = or_panic!(UnixListener::bind(&socket_path));
988        let thread = thread::spawn(move || {
989            let mut stream = or_panic!(listener.accept()).0;
990            let mut buf = [0; 5];
991            or_panic!(stream.read(&mut buf));
992            assert_eq!(&msg1[..], &buf[..]);
993            or_panic!(stream.write_all(msg2));
994        });
995
996        let mut stream = or_panic!(UnixStream::connect(&socket_path));
997        assert_eq!(Some(&b"the path"[..]),
998                   stream.peer_addr().unwrap().as_abstract());
999        or_panic!(stream.write_all(msg1));
1000        let mut buf = vec![];
1001        or_panic!(stream.read_to_end(&mut buf));
1002        assert_eq!(&msg2[..], &buf[..]);
1003        drop(stream);
1004
1005        thread.join().unwrap();
1006    }
1007
1008    #[test]
1009    fn try_clone() {
1010        let dir = or_panic!(TempDir::new("unix_socket"));
1011        let socket_path = dir.path().join("sock");
1012        let msg1 = b"hello";
1013        let msg2 = b"world";
1014
1015        let listener = or_panic!(UnixListener::bind(&socket_path));
1016        let thread = thread::spawn(move || {
1017            let mut stream = or_panic!(listener.accept()).0;
1018            or_panic!(stream.write_all(msg1));
1019            or_panic!(stream.write_all(msg2));
1020        });
1021
1022        let mut stream = or_panic!(UnixStream::connect(&socket_path));
1023        let mut stream2 = or_panic!(stream.try_clone());
1024
1025        let mut buf = [0; 5];
1026        or_panic!(stream.read(&mut buf));
1027        assert_eq!(&msg1[..], &buf[..]);
1028        or_panic!(stream2.read(&mut buf));
1029        assert_eq!(&msg2[..], &buf[..]);
1030
1031        thread.join().unwrap();
1032    }
1033
1034    #[test]
1035    fn iter() {
1036        let dir = or_panic!(TempDir::new("unix_socket"));
1037        let socket_path = dir.path().join("sock");
1038
1039        let listener = or_panic!(UnixListener::bind(&socket_path));
1040        let thread = thread::spawn(move || {
1041            for stream in listener.incoming().take(2) {
1042                let mut stream = or_panic!(stream);
1043                let mut buf = [0];
1044                or_panic!(stream.read(&mut buf));
1045            }
1046        });
1047
1048        for _ in 0..2 {
1049            let mut stream = or_panic!(UnixStream::connect(&socket_path));
1050            or_panic!(stream.write_all(&[0]));
1051        }
1052
1053        thread.join().unwrap();
1054    }
1055
1056    #[test]
1057    fn long_path() {
1058        let dir = or_panic!(TempDir::new("unix_socket"));
1059        let socket_path = dir.path()
1060                             .join("asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\
1061                                    sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf");
1062        match UnixStream::connect(&socket_path) {
1063            Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
1064            Err(e) => panic!("unexpected error {}", e),
1065            Ok(_) => panic!("unexpected success"),
1066        }
1067
1068        match UnixListener::bind(&socket_path) {
1069            Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
1070            Err(e) => panic!("unexpected error {}", e),
1071            Ok(_) => panic!("unexpected success"),
1072        }
1073
1074        match UnixDatagram::bind(&socket_path) {
1075            Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
1076            Err(e) => panic!("unexpected error {}", e),
1077            Ok(_) => panic!("unexpected success"),
1078        }
1079    }
1080
1081    #[test]
1082    fn timeouts() {
1083        let dir = or_panic!(TempDir::new("unix_socket"));
1084        let socket_path = dir.path().join("sock");
1085
1086        let _listener = or_panic!(UnixListener::bind(&socket_path));
1087
1088        let stream = or_panic!(UnixStream::connect(&socket_path));
1089        let dur = Duration::new(15410, 0);
1090
1091        assert_eq!(None, or_panic!(stream.read_timeout()));
1092
1093        or_panic!(stream.set_read_timeout(Some(dur)));
1094        assert_eq!(Some(dur), or_panic!(stream.read_timeout()));
1095
1096        assert_eq!(None, or_panic!(stream.write_timeout()));
1097
1098        or_panic!(stream.set_write_timeout(Some(dur)));
1099        assert_eq!(Some(dur), or_panic!(stream.write_timeout()));
1100
1101        or_panic!(stream.set_read_timeout(None));
1102        assert_eq!(None, or_panic!(stream.read_timeout()));
1103
1104        or_panic!(stream.set_write_timeout(None));
1105        assert_eq!(None, or_panic!(stream.write_timeout()));
1106    }
1107
1108    #[test]
1109    fn test_read_timeout() {
1110        let dir = or_panic!(TempDir::new("unix_socket"));
1111        let socket_path = dir.path().join("sock");
1112
1113        let _listener = or_panic!(UnixListener::bind(&socket_path));
1114
1115        let mut stream = or_panic!(UnixStream::connect(&socket_path));
1116        or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
1117
1118        let mut buf = [0; 10];
1119        let kind = stream.read(&mut buf).err().expect("expected error").kind();
1120        assert!(kind == io::ErrorKind::WouldBlock || kind == io::ErrorKind::TimedOut);
1121    }
1122
1123    #[test]
1124    fn test_read_with_timeout() {
1125        let dir = or_panic!(TempDir::new("unix_socket"));
1126        let socket_path = dir.path().join("sock");
1127
1128        let listener = or_panic!(UnixListener::bind(&socket_path));
1129
1130        let mut stream = or_panic!(UnixStream::connect(&socket_path));
1131        or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
1132
1133        let mut other_end = or_panic!(listener.accept()).0;
1134        or_panic!(other_end.write_all(b"hello world"));
1135
1136        let mut buf = [0; 11];
1137        or_panic!(stream.read(&mut buf));
1138        assert_eq!(b"hello world", &buf[..]);
1139
1140        let kind = stream.read(&mut buf).err().expect("expected error").kind();
1141        assert!(kind == io::ErrorKind::WouldBlock || kind == io::ErrorKind::TimedOut);
1142    }
1143
1144    #[test]
1145    fn test_unix_datagram() {
1146        let dir = or_panic!(TempDir::new("unix_socket"));
1147        let path1 = dir.path().join("sock1");
1148        let path2 = dir.path().join("sock2");
1149
1150        let sock1 = or_panic!(UnixDatagram::bind(&path1));
1151        let sock2 = or_panic!(UnixDatagram::bind(&path2));
1152
1153        let msg = b"hello world";
1154        or_panic!(sock1.send_to(msg, &path2));
1155        let mut buf = [0; 11];
1156        or_panic!(sock2.recv_from(&mut buf));
1157        assert_eq!(msg, &buf[..]);
1158    }
1159
1160    #[test]
1161    fn test_unnamed_unix_datagram() {
1162        let dir = or_panic!(TempDir::new("unix_socket"));
1163        let path1 = dir.path().join("sock1");
1164
1165        let sock1 = or_panic!(UnixDatagram::bind(&path1));
1166        let sock2 = or_panic!(UnixDatagram::unbound());
1167
1168        let msg = b"hello world";
1169        or_panic!(sock2.send_to(msg, &path1));
1170        let mut buf = [0; 11];
1171        let (usize, addr) = or_panic!(sock1.recv_from(&mut buf));
1172        assert_eq!(usize, 11);
1173        assert!(addr.is_unnamed());
1174        assert_eq!(msg, &buf[..]);
1175    }
1176
1177    #[test]
1178    fn test_connect_unix_datagram() {
1179        let dir = or_panic!(TempDir::new("unix_socket"));
1180        let path1 = dir.path().join("sock1");
1181        let path2 = dir.path().join("sock2");
1182
1183        let bsock1 = or_panic!(UnixDatagram::bind(&path1));
1184        let bsock2 = or_panic!(UnixDatagram::bind(&path2));
1185        let sock = or_panic!(UnixDatagram::unbound());
1186        or_panic!(sock.connect(&path1));
1187
1188        // Check send()
1189        let msg = b"hello there";
1190        or_panic!(sock.send(msg));
1191        let mut buf = [0; 11];
1192        let (usize, addr) = or_panic!(bsock1.recv_from(&mut buf));
1193        assert_eq!(usize, 11);
1194        assert!(addr.is_unnamed());
1195        assert_eq!(msg, &buf[..]);
1196
1197        // Changing default socket works too
1198        or_panic!(sock.connect(&path2));
1199        or_panic!(sock.send(msg));
1200        or_panic!(bsock2.recv_from(&mut buf));
1201    }
1202
1203    #[test]
1204    fn test_unix_datagram_recv() {
1205        let dir = or_panic!(TempDir::new("unix_socket"));
1206        let path1 = dir.path().join("sock1");
1207
1208        let sock1 = or_panic!(UnixDatagram::bind(&path1));
1209        let sock2 = or_panic!(UnixDatagram::unbound());
1210        or_panic!(sock2.connect(&path1));
1211
1212        let msg = b"hello world";
1213        or_panic!(sock2.send(msg));
1214        let mut buf = [0; 11];
1215        let size = or_panic!(sock1.recv(&mut buf));
1216        assert_eq!(size, 11);
1217        assert_eq!(msg, &buf[..]);
1218    }
1219
1220    #[test]
1221    fn datagram_pair() {
1222        let msg1 = b"hello";
1223        let msg2 = b"world!";
1224
1225        let (s1, s2) = or_panic!(UnixDatagram::pair());
1226        let thread = thread::spawn(move || {
1227            // s1 must be moved in or the test will hang!
1228            let mut buf = [0; 5];
1229            or_panic!(s1.recv(&mut buf));
1230            assert_eq!(&msg1[..], &buf[..]);
1231            or_panic!(s1.send(msg2));
1232        });
1233
1234        or_panic!(s2.send(msg1));
1235        let mut buf = [0; 6];
1236        or_panic!(s2.recv(&mut buf));
1237        assert_eq!(&msg2[..], &buf[..]);
1238        drop(s2);
1239
1240        thread.join().unwrap();
1241    }
1242}