1#![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 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 (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 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#[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 len = sun_path_offset() as libc::socklen_t; } 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 pub fn is_unnamed(&self) -> bool {
243 if let AddressKind::Unnamed = self.address() {
244 true
245 } else {
246 false
247 }
248 }
249
250 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 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
296pub mod os {
298 #[cfg(target_os = "linux")]
300 pub mod linux {
301 use {AddressKind, SocketAddr};
302
303 pub trait SocketAddrExt {
305 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
322pub 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 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 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 pub fn try_clone(&self) -> io::Result<UnixStream> {
391 Ok(UnixStream { inner: try!(self.inner.try_clone()) })
392 }
393
394 pub fn local_addr(&self) -> io::Result<SocketAddr> {
396 SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.inner.0, addr, len) })
397 }
398
399 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
401 SocketAddr::new(|addr, len| unsafe { libc::getpeername(self.inner.0, addr, len) })
402 }
403
404 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
410 self.inner.set_timeout(timeout, libc::SO_RCVTIMEO)
411 }
412
413 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
419 self.inner.set_timeout(timeout, libc::SO_SNDTIMEO)
420 }
421
422 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
424 self.inner.timeout(libc::SO_RCVTIMEO)
425 }
426
427 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
429 self.inner.timeout(libc::SO_SNDTIMEO)
430 }
431
432 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
434 self.inner.set_nonblocking(nonblocking)
435 }
436
437 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
439 self.inner.take_error()
440 }
441
442 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
510pub 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 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 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 pub fn try_clone(&self) -> io::Result<UnixListener> {
599 Ok(UnixListener { inner: try!(self.inner.try_clone()) })
600 }
601
602 pub fn local_addr(&self) -> io::Result<SocketAddr> {
604 SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.inner.0, addr, len) })
605 }
606
607 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
609 self.inner.set_nonblocking(nonblocking)
610 }
611
612 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
614 self.inner.take_error()
615 }
616
617 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#[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
675pub 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 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 pub fn unbound() -> io::Result<UnixDatagram> {
727 let inner = try!(Inner::new(libc::SOCK_DGRAM));
728 Ok(UnixDatagram { inner: inner })
729 }
730
731 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 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 pub fn local_addr(&self) -> io::Result<SocketAddr> {
755 SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.inner.0, addr, len) })
756 }
757
758 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
762 SocketAddr::new(|addr, len| unsafe { libc::getpeername(self.inner.0, addr, len) })
763 }
764
765 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 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 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 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 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
844 self.inner.set_timeout(timeout, libc::SO_RCVTIMEO)
845 }
846
847 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
853 self.inner.set_timeout(timeout, libc::SO_SNDTIMEO)
854 }
855
856 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
858 self.inner.timeout(libc::SO_RCVTIMEO)
859 }
860
861 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
863 self.inner.timeout(libc::SO_SNDTIMEO)
864 }
865
866 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
868 self.inner.set_nonblocking(nonblocking)
869 }
870
871 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
873 self.inner.take_error()
874 }
875
876 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 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 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 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 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}