]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/unix/ext/net.rs
Fix tidy checks
[rust.git] / src / libstd / sys / unix / ext / net.rs
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.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![stable(feature = "unix_socket", since = "1.10.0")]
12
13 //! Unix-specific networking functionality
14
15 #[cfg(unix)]
16 use libc;
17
18 // FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here?
19 #[cfg(not(unix))]
20 mod libc {
21     pub use libc::c_int;
22     pub type socklen_t = u32;
23     pub struct sockaddr;
24     #[derive(Clone)]
25     pub struct sockaddr_un;
26 }
27
28 use fmt;
29 use io;
30 use mem;
31 use net::{self, Shutdown};
32 use os::unix::ffi::OsStrExt;
33 use os::unix::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd};
34 use path::Path;
35 use time::Duration;
36 use sys::ext::unixsocket as inner;
37 use sys::net::Socket;
38 use sys::{self, cvt};
39 use sys_common::{self, AsInner, FromInner, IntoInner};
40
41 #[stable(feature = "unix_socket", since = "1.10.0")]
42 pub use sys_common::unixsocket::*;
43
44 #[cfg(any(target_os = "linux", target_os = "android",
45           target_os = "dragonfly", target_os = "freebsd",
46           target_os = "openbsd", target_os = "netbsd",
47           target_os = "haiku", target_os = "bitrig"))]
48 pub(crate) use libc::MSG_NOSIGNAL;
49 #[cfg(not(any(target_os = "linux", target_os = "android",
50               target_os = "dragonfly", target_os = "freebsd",
51               target_os = "openbsd", target_os = "netbsd",
52               target_os = "haiku", target_os = "bitrig")))]
53 pub(crate) const MSG_NOSIGNAL: libc::c_int = 0x0;
54
55 pub(crate) fn sun_path_offset() -> usize {
56     // Work with an actual instance of the type since using a null pointer is UB
57     let addr: libc::sockaddr_un = unsafe { mem::uninitialized() };
58     let base = &addr as *const _ as usize;
59     let path = &addr.sun_path as *const _ as usize;
60     path - base
61 }
62
63 pub(crate) unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::socklen_t)> {
64     let mut addr: libc::sockaddr_un = mem::zeroed();
65     addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
66
67     let bytes = path.as_os_str().as_bytes();
68
69     if bytes.contains(&0) {
70         return Err(io::Error::new(io::ErrorKind::InvalidInput,
71                                   "paths may not contain interior null bytes"));
72     }
73
74     if bytes.len() >= addr.sun_path.len() {
75         return Err(io::Error::new(io::ErrorKind::InvalidInput,
76                                   "path must be shorter than SUN_LEN"));
77     }
78     for (dst, src) in addr.sun_path.iter_mut().zip(bytes.iter()) {
79         *dst = *src as libc::c_char;
80     }
81     // null byte for pathname addresses is already there because we zeroed the
82     // struct
83
84     let mut len = sun_path_offset() + bytes.len();
85     match bytes.get(0) {
86         Some(&0) | None => {}
87         Some(_) => len += 1,
88     }
89     Ok((addr, len as libc::socklen_t))
90 }
91
92 #[stable(feature = "into_raw_os", since = "1.4.0")]
93 impl AsRawFd for net::TcpStream {
94     fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
95 }
96
97 #[stable(feature = "into_raw_os", since = "1.4.0")]
98 impl AsRawFd for net::TcpListener {
99     fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
100 }
101
102 #[stable(feature = "into_raw_os", since = "1.4.0")]
103 impl AsRawFd for net::UdpSocket {
104     fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
105 }
106
107 #[stable(feature = "into_raw_os", since = "1.4.0")]
108 impl FromRawFd for net::TcpStream {
109     unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
110         let socket = sys::net::Socket::from_inner(fd);
111         net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(socket))
112     }
113 }
114
115 #[stable(feature = "into_raw_os", since = "1.4.0")]
116 impl FromRawFd for net::TcpListener {
117     unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
118         let socket = sys::net::Socket::from_inner(fd);
119         net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(socket))
120     }
121 }
122
123 #[stable(feature = "into_raw_os", since = "1.4.0")]
124 impl FromRawFd for net::UdpSocket {
125     unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
126         let socket = sys::net::Socket::from_inner(fd);
127         net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(socket))
128     }
129 }
130
131 #[stable(feature = "into_raw_os", since = "1.4.0")]
132 impl IntoRawFd for net::TcpStream {
133     fn into_raw_fd(self) -> RawFd {
134         self.into_inner().into_socket().into_inner()
135     }
136 }
137 #[stable(feature = "into_raw_os", since = "1.4.0")]
138 impl IntoRawFd for net::TcpListener {
139     fn into_raw_fd(self) -> RawFd {
140         self.into_inner().into_socket().into_inner()
141     }
142 }
143 #[stable(feature = "into_raw_os", since = "1.4.0")]
144 impl IntoRawFd for net::UdpSocket {
145     fn into_raw_fd(self) -> RawFd {
146         self.into_inner().into_socket().into_inner()
147     }
148 }
149
150 /// A Unix datagram socket.
151 ///
152 /// # Examples
153 ///
154 /// ```no_run
155 /// use std::os::unix::net::UnixDatagram;
156 ///
157 /// let socket = UnixDatagram::bind("/path/to/my/socket").unwrap();
158 /// socket.send_to(b"hello world", "/path/to/other/socket").unwrap();
159 /// let mut buf = [0; 100];
160 /// let (count, address) = socket.recv_from(&mut buf).unwrap();
161 /// println!("socket {:?} sent {:?}", address, &buf[..count]);
162 /// ```
163 #[stable(feature = "unix_socket", since = "1.10.0")]
164 pub struct UnixDatagram(Socket);
165
166 #[stable(feature = "unix_socket", since = "1.10.0")]
167 impl fmt::Debug for UnixDatagram {
168     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
169         let mut builder = fmt.debug_struct("UnixDatagram");
170         builder.field("fd", self.0.as_inner());
171         if let Ok(addr) = self.local_addr() {
172             builder.field("local", &addr);
173         }
174         if let Ok(addr) = self.peer_addr() {
175             builder.field("peer", &addr);
176         }
177         builder.finish()
178     }
179 }
180
181 impl UnixDatagram {
182     /// Creates a Unix datagram socket bound to the given path.
183     ///
184     /// # Examples
185     ///
186     /// ```no_run
187     /// use std::os::unix::net::UnixDatagram;
188     ///
189     /// let sock = match UnixDatagram::bind("/path/to/the/socket") {
190     ///     Ok(sock) => sock,
191     ///     Err(e) => {
192     ///         println!("Couldn't bind: {:?}", e);
193     ///         return
194     ///     }
195     /// };
196     /// ```
197     #[stable(feature = "unix_socket", since = "1.10.0")]
198     pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
199         fn inner(path: &Path) -> io::Result<UnixDatagram> {
200             unsafe {
201                 let socket = UnixDatagram::unbound()?;
202                 let (addr, len) = sockaddr_un(path)?;
203
204                 cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len as _))?;
205
206                 Ok(socket)
207             }
208         }
209         inner(path.as_ref())
210     }
211
212     /// Creates a Unix Datagram socket which is not bound to any address.
213     ///
214     /// # Examples
215     ///
216     /// ```no_run
217     /// use std::os::unix::net::UnixDatagram;
218     ///
219     /// let sock = match UnixDatagram::unbound() {
220     ///     Ok(sock) => sock,
221     ///     Err(e) => {
222     ///         println!("Couldn't unbound: {:?}", e);
223     ///         return
224     ///     }
225     /// };
226     /// ```
227     #[stable(feature = "unix_socket", since = "1.10.0")]
228     pub fn unbound() -> io::Result<UnixDatagram> {
229         let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?;
230         Ok(UnixDatagram(inner))
231     }
232
233     /// Create an unnamed pair of connected sockets.
234     ///
235     /// Returns two `UnixDatagrams`s which are connected to each other.
236     ///
237     /// # Examples
238     ///
239     /// ```no_run
240     /// use std::os::unix::net::UnixDatagram;
241     ///
242     /// let (sock1, sock2) = match UnixDatagram::pair() {
243     ///     Ok((sock1, sock2)) => (sock1, sock2),
244     ///     Err(e) => {
245     ///         println!("Couldn't unbound: {:?}", e);
246     ///         return
247     ///     }
248     /// };
249     /// ```
250     #[stable(feature = "unix_socket", since = "1.10.0")]
251     pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
252         let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?;
253         Ok((UnixDatagram(i1), UnixDatagram(i2)))
254     }
255
256     /// Connects the socket to the specified address.
257     ///
258     /// The [`send`] method may be used to send data to the specified address.
259     /// [`recv`] and [`recv_from`] will only receive data from that address.
260     ///
261     /// [`send`]: #method.send
262     /// [`recv`]: #method.recv
263     /// [`recv_from`]: #method.recv_from
264     ///
265     /// # Examples
266     ///
267     /// ```no_run
268     /// use std::os::unix::net::UnixDatagram;
269     ///
270     /// let sock = UnixDatagram::unbound().unwrap();
271     /// match sock.connect("/path/to/the/socket") {
272     ///     Ok(sock) => sock,
273     ///     Err(e) => {
274     ///         println!("Couldn't connect: {:?}", e);
275     ///         return
276     ///     }
277     /// };
278     /// ```
279     #[stable(feature = "unix_socket", since = "1.10.0")]
280     pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
281         fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> {
282             unsafe {
283                 let (addr, len) = sockaddr_un(path)?;
284
285                 cvt(libc::connect(*d.0.as_inner(), &addr as *const _ as *const _, len))?;
286
287                 Ok(())
288             }
289         }
290         inner(self, path.as_ref())
291     }
292
293     /// Creates a new independently owned handle to the underlying socket.
294     ///
295     /// The returned `UnixDatagram` is a reference to the same socket that this
296     /// object references. Both handles can be used to accept incoming
297     /// connections and options set on one side will affect the other.
298     ///
299     /// # Examples
300     ///
301     /// ```no_run
302     /// use std::os::unix::net::UnixDatagram;
303     ///
304     /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
305     ///
306     /// let sock_copy = sock.try_clone().expect("try_clone failed");
307     /// ```
308     #[stable(feature = "unix_socket", since = "1.10.0")]
309     pub fn try_clone(&self) -> io::Result<UnixDatagram> {
310         self.0.duplicate().map(UnixDatagram)
311     }
312
313     /// Returns the address of this socket.
314     ///
315     /// # Examples
316     ///
317     /// ```no_run
318     /// use std::os::unix::net::UnixDatagram;
319     ///
320     /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
321     ///
322     /// let addr = sock.local_addr().expect("Couldn't get local address");
323     /// ```
324     #[stable(feature = "unix_socket", since = "1.10.0")]
325     pub fn local_addr(&self) -> io::Result<SocketAddr> {
326         inner::SocketAddr::new(|addr, len| unsafe {
327             libc::getsockname(*self.0.as_inner(), addr, len)
328         }).map(SocketAddr)
329     }
330
331     /// Returns the address of this socket's peer.
332     ///
333     /// The [`connect`] method will connect the socket to a peer.
334     ///
335     /// [`connect`]: #method.connect
336     ///
337     /// # Examples
338     ///
339     /// ```no_run
340     /// use std::os::unix::net::UnixDatagram;
341     ///
342     /// let sock = UnixDatagram::unbound().unwrap();
343     /// sock.connect("/path/to/the/socket").unwrap();
344     ///
345     /// let addr = sock.peer_addr().expect("Couldn't get peer address");
346     /// ```
347     #[stable(feature = "unix_socket", since = "1.10.0")]
348     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
349         inner::SocketAddr::new(|addr, len| unsafe {
350             libc::getsockname(*self.0.as_inner(), addr, len)
351         }).map(SocketAddr)
352     }
353
354     /// Receives data from the socket.
355     ///
356     /// On success, returns the number of bytes read and the address from
357     /// whence the data came.
358     ///
359     /// # Examples
360     ///
361     /// ```no_run
362     /// use std::os::unix::net::UnixDatagram;
363     ///
364     /// let sock = UnixDatagram::unbound().unwrap();
365     /// let mut buf = vec![0; 10];
366     /// match sock.recv_from(buf.as_mut_slice()) {
367     ///     Ok((size, sender)) => println!("received {} bytes from {:?}", size, sender),
368     ///     Err(e) => println!("recv_from function failed: {:?}", e),
369     /// }
370     /// ```
371     #[stable(feature = "unix_socket", since = "1.10.0")]
372     pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
373         let mut count = 0;
374         let addr = SocketAddr(inner::SocketAddr::new(|addr, len| {
375             unsafe {
376                 count = libc::recvfrom(*self.0.as_inner(),
377                                        buf.as_mut_ptr() as *mut _,
378                                        buf.len(),
379                                        0,
380                                        addr,
381                                        len);
382                 if count > 0 {
383                     1
384                 } else if count == 0 {
385                     0
386                 } else {
387                     -1
388                 }
389             }
390         })?);
391
392         Ok((count as usize, addr))
393     }
394
395     /// Receives data from the socket.
396     ///
397     /// On success, returns the number of bytes read.
398     ///
399     /// # Examples
400     ///
401     /// ```no_run
402     /// use std::os::unix::net::UnixDatagram;
403     ///
404     /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
405     /// let mut buf = vec![0; 10];
406     /// sock.recv(buf.as_mut_slice()).expect("recv function failed");
407     /// ```
408     #[stable(feature = "unix_socket", since = "1.10.0")]
409     pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
410         self.0.read(buf)
411     }
412
413     /// Sends data on the socket to the specified address.
414     ///
415     /// On success, returns the number of bytes written.
416     ///
417     /// # Examples
418     ///
419     /// ```no_run
420     /// use std::os::unix::net::UnixDatagram;
421     ///
422     /// let sock = UnixDatagram::unbound().unwrap();
423     /// sock.send_to(b"omelette au fromage", "/some/sock").expect("send_to function failed");
424     /// ```
425     #[stable(feature = "unix_socket", since = "1.10.0")]
426     pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
427         fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result<usize> {
428             unsafe {
429                 let (addr, len) = sockaddr_un(path)?;
430
431                 let count = cvt(libc::sendto(*d.0.as_inner(),
432                                              buf.as_ptr() as *const _,
433                                              buf.len(),
434                                              MSG_NOSIGNAL,
435                                              &addr as *const _ as *const _,
436                                              len))?;
437                 Ok(count as usize)
438             }
439         }
440         inner(self, buf, path.as_ref())
441     }
442
443     /// Sends data on the socket to the socket's peer.
444     ///
445     /// The peer address may be set by the `connect` method, and this method
446     /// will return an error if the socket has not already been connected.
447     ///
448     /// On success, returns the number of bytes written.
449     ///
450     /// # Examples
451     ///
452     /// ```no_run
453     /// use std::os::unix::net::UnixDatagram;
454     ///
455     /// let sock = UnixDatagram::unbound().unwrap();
456     /// sock.connect("/some/sock").expect("Couldn't connect");
457     /// sock.send(b"omelette au fromage").expect("send_to function failed");
458     /// ```
459     #[stable(feature = "unix_socket", since = "1.10.0")]
460     pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
461         self.0.write(buf)
462     }
463
464     /// Sets the read timeout for the socket.
465     ///
466     /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will
467     /// block indefinitely. An [`Err`] is returned if the zero [`Duration`]
468     /// is passed to this method.
469     ///
470     /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
471     /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
472     /// [`recv`]: #method.recv
473     /// [`recv_from`]: #method.recv_from
474     /// [`Duration`]: ../../../../std/time/struct.Duration.html
475     ///
476     /// # Examples
477     ///
478     /// ```
479     /// use std::os::unix::net::UnixDatagram;
480     /// use std::time::Duration;
481     ///
482     /// let sock = UnixDatagram::unbound().unwrap();
483     /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed");
484     /// ```
485     ///
486     /// An [`Err`] is returned if the zero [`Duration`] is passed to this
487     /// method:
488     ///
489     /// ```no_run
490     /// use std::io;
491     /// use std::os::unix::net::UnixDatagram;
492     /// use std::time::Duration;
493     ///
494     /// let socket = UnixDatagram::unbound().unwrap();
495     /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
496     /// let err = result.unwrap_err();
497     /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
498     /// ```
499     #[stable(feature = "unix_socket", since = "1.10.0")]
500     pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
501         self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
502     }
503
504     /// Sets the write timeout for the socket.
505     ///
506     /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will
507     /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
508     /// method.
509     ///
510     /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
511     /// [`send`]: #method.send
512     /// [`send_to`]: #method.send_to
513     /// [`Duration`]: ../../../../std/time/struct.Duration.html
514     ///
515     /// # Examples
516     ///
517     /// ```
518     /// use std::os::unix::net::UnixDatagram;
519     /// use std::time::Duration;
520     ///
521     /// let sock = UnixDatagram::unbound().unwrap();
522     /// sock.set_write_timeout(Some(Duration::new(1, 0)))
523     ///     .expect("set_write_timeout function failed");
524     /// ```
525     ///
526     /// An [`Err`] is returned if the zero [`Duration`] is passed to this
527     /// method:
528     ///
529     /// ```no_run
530     /// use std::io;
531     /// use std::os::unix::net::UnixDatagram;
532     /// use std::time::Duration;
533     ///
534     /// let socket = UnixDatagram::unbound().unwrap();
535     /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
536     /// let err = result.unwrap_err();
537     /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
538     /// ```
539     #[stable(feature = "unix_socket", since = "1.10.0")]
540     pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
541         self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
542     }
543
544     /// Returns the read timeout of this socket.
545     ///
546     /// # Examples
547     ///
548     /// ```
549     /// use std::os::unix::net::UnixDatagram;
550     /// use std::time::Duration;
551     ///
552     /// let sock = UnixDatagram::unbound().unwrap();
553     /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed");
554     /// assert_eq!(sock.read_timeout().unwrap(), Some(Duration::new(1, 0)));
555     /// ```
556     #[stable(feature = "unix_socket", since = "1.10.0")]
557     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
558         self.0.timeout(libc::SO_RCVTIMEO)
559     }
560
561     /// Returns the write timeout of this socket.
562     ///
563     /// # Examples
564     ///
565     /// ```
566     /// use std::os::unix::net::UnixDatagram;
567     /// use std::time::Duration;
568     ///
569     /// let sock = UnixDatagram::unbound().unwrap();
570     /// sock.set_write_timeout(Some(Duration::new(1, 0)))
571     ///     .expect("set_write_timeout function failed");
572     /// assert_eq!(sock.write_timeout().unwrap(), Some(Duration::new(1, 0)));
573     /// ```
574     #[stable(feature = "unix_socket", since = "1.10.0")]
575     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
576         self.0.timeout(libc::SO_SNDTIMEO)
577     }
578
579     /// Moves the socket into or out of nonblocking mode.
580     ///
581     /// # Examples
582     ///
583     /// ```
584     /// use std::os::unix::net::UnixDatagram;
585     ///
586     /// let sock = UnixDatagram::unbound().unwrap();
587     /// sock.set_nonblocking(true).expect("set_nonblocking function failed");
588     /// ```
589     #[stable(feature = "unix_socket", since = "1.10.0")]
590     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
591         self.0.set_nonblocking(nonblocking)
592     }
593
594     /// Returns the value of the `SO_ERROR` option.
595     ///
596     /// # Examples
597     ///
598     /// ```no_run
599     /// use std::os::unix::net::UnixDatagram;
600     ///
601     /// let sock = UnixDatagram::unbound().unwrap();
602     /// if let Ok(Some(err)) = sock.take_error() {
603     ///     println!("Got error: {:?}", err);
604     /// }
605     /// ```
606     #[stable(feature = "unix_socket", since = "1.10.0")]
607     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
608         self.0.take_error()
609     }
610
611     /// Shut down the read, write, or both halves of this connection.
612     ///
613     /// This function will cause all pending and future I/O calls on the
614     /// specified portions to immediately return with an appropriate value
615     /// (see the documentation of [`Shutdown`]).
616     ///
617     /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
618     ///
619     /// ```no_run
620     /// use std::os::unix::net::UnixDatagram;
621     /// use std::net::Shutdown;
622     ///
623     /// let sock = UnixDatagram::unbound().unwrap();
624     /// sock.shutdown(Shutdown::Both).expect("shutdown function failed");
625     /// ```
626     #[stable(feature = "unix_socket", since = "1.10.0")]
627     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
628         self.0.shutdown(how)
629     }
630 }
631
632 #[stable(feature = "unix_socket", since = "1.10.0")]
633 impl AsRawFd for UnixDatagram {
634     fn as_raw_fd(&self) -> RawFd {
635         *self.0.as_inner()
636     }
637 }
638
639 #[stable(feature = "unix_socket", since = "1.10.0")]
640 impl FromRawFd for UnixDatagram {
641     unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
642         UnixDatagram(Socket::from_inner(fd))
643     }
644 }
645
646 #[stable(feature = "unix_socket", since = "1.10.0")]
647 impl IntoRawFd for UnixDatagram {
648     fn into_raw_fd(self) -> RawFd {
649         self.0.into_inner()
650     }
651 }
652
653 #[cfg(all(test, not(target_os = "emscripten")))]
654 mod test {
655     use thread;
656     use io::{self, ErrorKind};
657     use io::prelude::*;
658     use time::Duration;
659     use sys_common::io::test::tmpdir;
660
661     use super::*;
662
663     macro_rules! or_panic {
664         ($e:expr) => {
665             match $e {
666                 Ok(e) => e,
667                 Err(e) => panic!("{}", e),
668             }
669         }
670     }
671
672     #[test]
673     fn basic() {
674         let dir = tmpdir();
675         let socket_path = dir.path().join("sock");
676         let msg1 = b"hello";
677         let msg2 = b"world!";
678
679         let listener = or_panic!(UnixListener::bind(&socket_path));
680         let thread = thread::spawn(move || {
681             let mut stream = or_panic!(listener.accept()).0;
682             let mut buf = [0; 5];
683             or_panic!(stream.read(&mut buf));
684             assert_eq!(&msg1[..], &buf[..]);
685             or_panic!(stream.write_all(msg2));
686         });
687
688         let mut stream = or_panic!(UnixStream::connect(&socket_path));
689         assert_eq!(Some(&*socket_path),
690                    stream.peer_addr().unwrap().as_pathname());
691         or_panic!(stream.write_all(msg1));
692         let mut buf = vec![];
693         or_panic!(stream.read_to_end(&mut buf));
694         assert_eq!(&msg2[..], &buf[..]);
695         drop(stream);
696
697         thread.join().unwrap();
698     }
699
700     #[test]
701     fn pair() {
702         let msg1 = b"hello";
703         let msg2 = b"world!";
704
705         let (mut s1, mut s2) = or_panic!(UnixStream::pair());
706         let thread = thread::spawn(move || {
707             // s1 must be moved in or the test will hang!
708             let mut buf = [0; 5];
709             or_panic!(s1.read(&mut buf));
710             assert_eq!(&msg1[..], &buf[..]);
711             or_panic!(s1.write_all(msg2));
712         });
713
714         or_panic!(s2.write_all(msg1));
715         let mut buf = vec![];
716         or_panic!(s2.read_to_end(&mut buf));
717         assert_eq!(&msg2[..], &buf[..]);
718         drop(s2);
719
720         thread.join().unwrap();
721     }
722
723     #[test]
724     fn try_clone() {
725         let dir = tmpdir();
726         let socket_path = dir.path().join("sock");
727         let msg1 = b"hello";
728         let msg2 = b"world";
729
730         let listener = or_panic!(UnixListener::bind(&socket_path));
731         let thread = thread::spawn(move || {
732             let mut stream = or_panic!(listener.accept()).0;
733             or_panic!(stream.write_all(msg1));
734             or_panic!(stream.write_all(msg2));
735         });
736
737         let mut stream = or_panic!(UnixStream::connect(&socket_path));
738         let mut stream2 = or_panic!(stream.try_clone());
739
740         let mut buf = [0; 5];
741         or_panic!(stream.read(&mut buf));
742         assert_eq!(&msg1[..], &buf[..]);
743         or_panic!(stream2.read(&mut buf));
744         assert_eq!(&msg2[..], &buf[..]);
745
746         thread.join().unwrap();
747     }
748
749     #[test]
750     fn iter() {
751         let dir = tmpdir();
752         let socket_path = dir.path().join("sock");
753
754         let listener = or_panic!(UnixListener::bind(&socket_path));
755         let thread = thread::spawn(move || {
756             for stream in listener.incoming().take(2) {
757                 let mut stream = or_panic!(stream);
758                 let mut buf = [0];
759                 or_panic!(stream.read(&mut buf));
760             }
761         });
762
763         for _ in 0..2 {
764             let mut stream = or_panic!(UnixStream::connect(&socket_path));
765             or_panic!(stream.write_all(&[0]));
766         }
767
768         thread.join().unwrap();
769     }
770
771     #[test]
772     fn long_path() {
773         let dir = tmpdir();
774         let socket_path = dir.path()
775                              .join("asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\
776                                     sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf");
777         match UnixStream::connect(&socket_path) {
778             Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
779             Err(e) => panic!("unexpected error {}", e),
780             Ok(_) => panic!("unexpected success"),
781         }
782
783         match UnixListener::bind(&socket_path) {
784             Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
785             Err(e) => panic!("unexpected error {}", e),
786             Ok(_) => panic!("unexpected success"),
787         }
788
789         match UnixDatagram::bind(&socket_path) {
790             Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
791             Err(e) => panic!("unexpected error {}", e),
792             Ok(_) => panic!("unexpected success"),
793         }
794     }
795
796     #[test]
797     fn timeouts() {
798         let dir = tmpdir();
799         let socket_path = dir.path().join("sock");
800
801         let _listener = or_panic!(UnixListener::bind(&socket_path));
802
803         let stream = or_panic!(UnixStream::connect(&socket_path));
804         let dur = Duration::new(15410, 0);
805
806         assert_eq!(None, or_panic!(stream.read_timeout()));
807
808         or_panic!(stream.set_read_timeout(Some(dur)));
809         assert_eq!(Some(dur), or_panic!(stream.read_timeout()));
810
811         assert_eq!(None, or_panic!(stream.write_timeout()));
812
813         or_panic!(stream.set_write_timeout(Some(dur)));
814         assert_eq!(Some(dur), or_panic!(stream.write_timeout()));
815
816         or_panic!(stream.set_read_timeout(None));
817         assert_eq!(None, or_panic!(stream.read_timeout()));
818
819         or_panic!(stream.set_write_timeout(None));
820         assert_eq!(None, or_panic!(stream.write_timeout()));
821     }
822
823     #[test]
824     fn test_read_timeout() {
825         let dir = tmpdir();
826         let socket_path = dir.path().join("sock");
827
828         let _listener = or_panic!(UnixListener::bind(&socket_path));
829
830         let mut stream = or_panic!(UnixStream::connect(&socket_path));
831         or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
832
833         let mut buf = [0; 10];
834         let kind = stream.read(&mut buf).err().expect("expected error").kind();
835         assert!(kind == io::ErrorKind::WouldBlock || kind == io::ErrorKind::TimedOut);
836     }
837
838     #[test]
839     fn test_read_with_timeout() {
840         let dir = tmpdir();
841         let socket_path = dir.path().join("sock");
842
843         let listener = or_panic!(UnixListener::bind(&socket_path));
844
845         let mut stream = or_panic!(UnixStream::connect(&socket_path));
846         or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
847
848         let mut other_end = or_panic!(listener.accept()).0;
849         or_panic!(other_end.write_all(b"hello world"));
850
851         let mut buf = [0; 11];
852         or_panic!(stream.read(&mut buf));
853         assert_eq!(b"hello world", &buf[..]);
854
855         let kind = stream.read(&mut buf).err().expect("expected error").kind();
856         assert!(kind == io::ErrorKind::WouldBlock || kind == io::ErrorKind::TimedOut);
857     }
858
859     // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
860     // when passed zero Durations
861     #[test]
862     fn test_unix_stream_timeout_zero_duration() {
863         let dir = tmpdir();
864         let socket_path = dir.path().join("sock");
865
866         let listener = or_panic!(UnixListener::bind(&socket_path));
867         let stream = or_panic!(UnixStream::connect(&socket_path));
868
869         let result = stream.set_write_timeout(Some(Duration::new(0, 0)));
870         let err = result.unwrap_err();
871         assert_eq!(err.kind(), ErrorKind::InvalidInput);
872
873         let result = stream.set_read_timeout(Some(Duration::new(0, 0)));
874         let err = result.unwrap_err();
875         assert_eq!(err.kind(), ErrorKind::InvalidInput);
876
877         drop(listener);
878     }
879
880     #[test]
881     fn test_unix_datagram() {
882         let dir = tmpdir();
883         let path1 = dir.path().join("sock1");
884         let path2 = dir.path().join("sock2");
885
886         let sock1 = or_panic!(UnixDatagram::bind(&path1));
887         let sock2 = or_panic!(UnixDatagram::bind(&path2));
888
889         let msg = b"hello world";
890         or_panic!(sock1.send_to(msg, &path2));
891         let mut buf = [0; 11];
892         or_panic!(sock2.recv_from(&mut buf));
893         assert_eq!(msg, &buf[..]);
894     }
895
896     #[test]
897     fn test_unnamed_unix_datagram() {
898         let dir = tmpdir();
899         let path1 = dir.path().join("sock1");
900
901         let sock1 = or_panic!(UnixDatagram::bind(&path1));
902         let sock2 = or_panic!(UnixDatagram::unbound());
903
904         let msg = b"hello world";
905         or_panic!(sock2.send_to(msg, &path1));
906         let mut buf = [0; 11];
907         let (usize, addr) = or_panic!(sock1.recv_from(&mut buf));
908         assert_eq!(usize, 11);
909         assert!(addr.is_unnamed());
910         assert_eq!(msg, &buf[..]);
911     }
912
913     #[test]
914     fn test_connect_unix_datagram() {
915         let dir = tmpdir();
916         let path1 = dir.path().join("sock1");
917         let path2 = dir.path().join("sock2");
918
919         let bsock1 = or_panic!(UnixDatagram::bind(&path1));
920         let bsock2 = or_panic!(UnixDatagram::bind(&path2));
921         let sock = or_panic!(UnixDatagram::unbound());
922         or_panic!(sock.connect(&path1));
923
924         // Check send()
925         let msg = b"hello there";
926         or_panic!(sock.send(msg));
927         let mut buf = [0; 11];
928         let (usize, addr) = or_panic!(bsock1.recv_from(&mut buf));
929         assert_eq!(usize, 11);
930         assert!(addr.is_unnamed());
931         assert_eq!(msg, &buf[..]);
932
933         // Changing default socket works too
934         or_panic!(sock.connect(&path2));
935         or_panic!(sock.send(msg));
936         or_panic!(bsock2.recv_from(&mut buf));
937     }
938
939     #[test]
940     fn test_unix_datagram_recv() {
941         let dir = tmpdir();
942         let path1 = dir.path().join("sock1");
943
944         let sock1 = or_panic!(UnixDatagram::bind(&path1));
945         let sock2 = or_panic!(UnixDatagram::unbound());
946         or_panic!(sock2.connect(&path1));
947
948         let msg = b"hello world";
949         or_panic!(sock2.send(msg));
950         let mut buf = [0; 11];
951         let size = or_panic!(sock1.recv(&mut buf));
952         assert_eq!(size, 11);
953         assert_eq!(msg, &buf[..]);
954     }
955
956     #[test]
957     fn datagram_pair() {
958         let msg1 = b"hello";
959         let msg2 = b"world!";
960
961         let (s1, s2) = or_panic!(UnixDatagram::pair());
962         let thread = thread::spawn(move || {
963             // s1 must be moved in or the test will hang!
964             let mut buf = [0; 5];
965             or_panic!(s1.recv(&mut buf));
966             assert_eq!(&msg1[..], &buf[..]);
967             or_panic!(s1.send(msg2));
968         });
969
970         or_panic!(s2.send(msg1));
971         let mut buf = [0; 6];
972         or_panic!(s2.recv(&mut buf));
973         assert_eq!(&msg2[..], &buf[..]);
974         drop(s2);
975
976         thread.join().unwrap();
977     }
978
979     // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
980     // when passed zero Durations
981     #[test]
982     fn test_unix_datagram_timeout_zero_duration() {
983         let dir = tmpdir();
984         let path = dir.path().join("sock");
985
986         let datagram = or_panic!(UnixDatagram::bind(&path));
987
988         let result = datagram.set_write_timeout(Some(Duration::new(0, 0)));
989         let err = result.unwrap_err();
990         assert_eq!(err.kind(), ErrorKind::InvalidInput);
991
992         let result = datagram.set_read_timeout(Some(Duration::new(0, 0)));
993         let err = result.unwrap_err();
994         assert_eq!(err.kind(), ErrorKind::InvalidInput);
995     }
996
997     #[test]
998     fn abstract_namespace_not_allowed() {
999         assert!(UnixStream::connect("\0asdf").is_err());
1000     }
1001 }