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