]> git.proxmox.com Git - rustc.git/blob - src/libstd/sys/unix/ext/net.rs
New upstream version 1.34.2+dfsg1
[rustc.git] / src / libstd / sys / unix / ext / net.rs
1 #![stable(feature = "unix_socket", since = "1.10.0")]
2
3 //! Unix-specific networking functionality
4
5 #[cfg(unix)]
6 use libc;
7
8 // FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here?
9 #[cfg(not(unix))]
10 mod libc {
11 pub use libc::c_int;
12 pub type socklen_t = u32;
13 pub struct sockaddr;
14 #[derive(Clone)]
15 pub struct sockaddr_un;
16 }
17
18 use ascii;
19 use ffi::OsStr;
20 use fmt;
21 use io::{self, Initializer, IoVec, IoVecMut};
22 use mem;
23 use net::{self, Shutdown};
24 use os::unix::ffi::OsStrExt;
25 use os::unix::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd};
26 use path::Path;
27 use time::Duration;
28 use sys::{self, cvt};
29 use sys::net::Socket;
30 use sys_common::{self, AsInner, FromInner, IntoInner};
31
32 #[cfg(any(target_os = "linux", target_os = "android",
33 target_os = "dragonfly", target_os = "freebsd",
34 target_os = "openbsd", target_os = "netbsd",
35 target_os = "haiku", target_os = "bitrig"))]
36 use libc::MSG_NOSIGNAL;
37 #[cfg(not(any(target_os = "linux", target_os = "android",
38 target_os = "dragonfly", target_os = "freebsd",
39 target_os = "openbsd", target_os = "netbsd",
40 target_os = "haiku", target_os = "bitrig")))]
41 const MSG_NOSIGNAL: libc::c_int = 0x0;
42
43 fn sun_path_offset() -> usize {
44 // Work with an actual instance of the type since using a null pointer is UB
45 let addr: libc::sockaddr_un = unsafe { 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 unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::socklen_t)> {
52 let mut addr: libc::sockaddr_un = mem::zeroed();
53 addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
54
55 let bytes = path.as_os_str().as_bytes();
56
57 if bytes.contains(&0) {
58 return Err(io::Error::new(io::ErrorKind::InvalidInput,
59 "paths may not contain interior null bytes"));
60 }
61
62 if bytes.len() >= addr.sun_path.len() {
63 return Err(io::Error::new(io::ErrorKind::InvalidInput,
64 "path must be shorter than SUN_LEN"));
65 }
66 for (dst, src) in addr.sun_path.iter_mut().zip(bytes.iter()) {
67 *dst = *src as libc::c_char;
68 }
69 // null byte for pathname addresses is already there because we zeroed the
70 // struct
71
72 let mut len = sun_path_offset() + bytes.len();
73 match bytes.get(0) {
74 Some(&0) | None => {}
75 Some(_) => len += 1,
76 }
77 Ok((addr, len as libc::socklen_t))
78 }
79
80 enum AddressKind<'a> {
81 Unnamed,
82 Pathname(&'a Path),
83 Abstract(&'a [u8]),
84 }
85
86 /// An address associated with a Unix socket.
87 ///
88 /// # Examples
89 ///
90 /// ```
91 /// use std::os::unix::net::UnixListener;
92 ///
93 /// let socket = match UnixListener::bind("/tmp/sock") {
94 /// Ok(sock) => sock,
95 /// Err(e) => {
96 /// println!("Couldn't bind: {:?}", e);
97 /// return
98 /// }
99 /// };
100 /// let addr = socket.local_addr().expect("Couldn't get local address");
101 /// ```
102 #[derive(Clone)]
103 #[stable(feature = "unix_socket", since = "1.10.0")]
104 pub struct SocketAddr {
105 addr: libc::sockaddr_un,
106 len: libc::socklen_t,
107 }
108
109 impl SocketAddr {
110 fn new<F>(f: F) -> io::Result<SocketAddr>
111 where F: FnOnce(*mut libc::sockaddr, *mut libc::socklen_t) -> libc::c_int
112 {
113 unsafe {
114 let mut addr: libc::sockaddr_un = mem::zeroed();
115 let mut len = mem::size_of::<libc::sockaddr_un>() as libc::socklen_t;
116 cvt(f(&mut addr as *mut _ as *mut _, &mut len))?;
117 SocketAddr::from_parts(addr, len)
118 }
119 }
120
121 fn from_parts(addr: libc::sockaddr_un, mut len: libc::socklen_t) -> io::Result<SocketAddr> {
122 if len == 0 {
123 // When there is a datagram from unnamed unix socket
124 // linux returns zero bytes of address
125 len = sun_path_offset() as libc::socklen_t; // i.e., zero-length address
126 } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
127 return Err(io::Error::new(io::ErrorKind::InvalidInput,
128 "file descriptor did not correspond to a Unix socket"));
129 }
130
131 Ok(SocketAddr {
132 addr,
133 len,
134 })
135 }
136
137 /// Returns `true` if the address is unnamed.
138 ///
139 /// # Examples
140 ///
141 /// A named address:
142 ///
143 /// ```no_run
144 /// use std::os::unix::net::UnixListener;
145 ///
146 /// let socket = UnixListener::bind("/tmp/sock").unwrap();
147 /// let addr = socket.local_addr().expect("Couldn't get local address");
148 /// assert_eq!(addr.is_unnamed(), false);
149 /// ```
150 ///
151 /// An unnamed address:
152 ///
153 /// ```
154 /// use std::os::unix::net::UnixDatagram;
155 ///
156 /// let socket = UnixDatagram::unbound().unwrap();
157 /// let addr = socket.local_addr().expect("Couldn't get local address");
158 /// assert_eq!(addr.is_unnamed(), true);
159 /// ```
160 #[stable(feature = "unix_socket", since = "1.10.0")]
161 pub fn is_unnamed(&self) -> bool {
162 if let AddressKind::Unnamed = self.address() {
163 true
164 } else {
165 false
166 }
167 }
168
169 /// Returns the contents of this address if it is a `pathname` address.
170 ///
171 /// # Examples
172 ///
173 /// With a pathname:
174 ///
175 /// ```no_run
176 /// use std::os::unix::net::UnixListener;
177 /// use std::path::Path;
178 ///
179 /// let socket = UnixListener::bind("/tmp/sock").unwrap();
180 /// let addr = socket.local_addr().expect("Couldn't get local address");
181 /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock")));
182 /// ```
183 ///
184 /// Without a pathname:
185 ///
186 /// ```
187 /// use std::os::unix::net::UnixDatagram;
188 ///
189 /// let socket = UnixDatagram::unbound().unwrap();
190 /// let addr = socket.local_addr().expect("Couldn't get local address");
191 /// assert_eq!(addr.as_pathname(), None);
192 /// ```
193 #[stable(feature = "unix_socket", since = "1.10.0")]
194 pub fn as_pathname(&self) -> Option<&Path> {
195 if let AddressKind::Pathname(path) = self.address() {
196 Some(path)
197 } else {
198 None
199 }
200 }
201
202 fn address<'a>(&'a self) -> AddressKind<'a> {
203 let len = self.len as usize - sun_path_offset();
204 let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
205
206 // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
207 if len == 0
208 || (cfg!(not(any(target_os = "linux", target_os = "android")))
209 && self.addr.sun_path[0] == 0)
210 {
211 AddressKind::Unnamed
212 } else if self.addr.sun_path[0] == 0 {
213 AddressKind::Abstract(&path[1..len])
214 } else {
215 AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref())
216 }
217 }
218 }
219
220 #[stable(feature = "unix_socket", since = "1.10.0")]
221 impl fmt::Debug for SocketAddr {
222 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
223 match self.address() {
224 AddressKind::Unnamed => write!(fmt, "(unnamed)"),
225 AddressKind::Abstract(name) => write!(fmt, "{} (abstract)", AsciiEscaped(name)),
226 AddressKind::Pathname(path) => write!(fmt, "{:?} (pathname)", path),
227 }
228 }
229 }
230
231 struct AsciiEscaped<'a>(&'a [u8]);
232
233 impl<'a> fmt::Display for AsciiEscaped<'a> {
234 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
235 write!(fmt, "\"")?;
236 for byte in self.0.iter().cloned().flat_map(ascii::escape_default) {
237 write!(fmt, "{}", byte as char)?;
238 }
239 write!(fmt, "\"")
240 }
241 }
242
243 /// A Unix stream socket.
244 ///
245 /// # Examples
246 ///
247 /// ```no_run
248 /// use std::os::unix::net::UnixStream;
249 /// use std::io::prelude::*;
250 ///
251 /// let mut stream = UnixStream::connect("/path/to/my/socket").unwrap();
252 /// stream.write_all(b"hello world").unwrap();
253 /// let mut response = String::new();
254 /// stream.read_to_string(&mut response).unwrap();
255 /// println!("{}", response);
256 /// ```
257 #[stable(feature = "unix_socket", since = "1.10.0")]
258 pub struct UnixStream(Socket);
259
260 #[stable(feature = "unix_socket", since = "1.10.0")]
261 impl fmt::Debug for UnixStream {
262 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
263 let mut builder = fmt.debug_struct("UnixStream");
264 builder.field("fd", self.0.as_inner());
265 if let Ok(addr) = self.local_addr() {
266 builder.field("local", &addr);
267 }
268 if let Ok(addr) = self.peer_addr() {
269 builder.field("peer", &addr);
270 }
271 builder.finish()
272 }
273 }
274
275 impl UnixStream {
276 /// Connects to the socket named by `path`.
277 ///
278 /// # Examples
279 ///
280 /// ```no_run
281 /// use std::os::unix::net::UnixStream;
282 ///
283 /// let socket = match UnixStream::connect("/tmp/sock") {
284 /// Ok(sock) => sock,
285 /// Err(e) => {
286 /// println!("Couldn't connect: {:?}", e);
287 /// return
288 /// }
289 /// };
290 /// ```
291 #[stable(feature = "unix_socket", since = "1.10.0")]
292 pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
293 fn inner(path: &Path) -> io::Result<UnixStream> {
294 unsafe {
295 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
296 let (addr, len) = sockaddr_un(path)?;
297
298 cvt(libc::connect(*inner.as_inner(), &addr as *const _ as *const _, len))?;
299 Ok(UnixStream(inner))
300 }
301 }
302 inner(path.as_ref())
303 }
304
305 /// Creates an unnamed pair of connected sockets.
306 ///
307 /// Returns two `UnixStream`s which are connected to each other.
308 ///
309 /// # Examples
310 ///
311 /// ```no_run
312 /// use std::os::unix::net::UnixStream;
313 ///
314 /// let (sock1, sock2) = match UnixStream::pair() {
315 /// Ok((sock1, sock2)) => (sock1, sock2),
316 /// Err(e) => {
317 /// println!("Couldn't create a pair of sockets: {:?}", e);
318 /// return
319 /// }
320 /// };
321 /// ```
322 #[stable(feature = "unix_socket", since = "1.10.0")]
323 pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
324 let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
325 Ok((UnixStream(i1), UnixStream(i2)))
326 }
327
328 /// Creates a new independently owned handle to the underlying socket.
329 ///
330 /// The returned `UnixStream` is a reference to the same stream that this
331 /// object references. Both handles will read and write the same stream of
332 /// data, and options set on one stream will be propagated to the other
333 /// stream.
334 ///
335 /// # Examples
336 ///
337 /// ```no_run
338 /// use std::os::unix::net::UnixStream;
339 ///
340 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
341 /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
342 /// ```
343 #[stable(feature = "unix_socket", since = "1.10.0")]
344 pub fn try_clone(&self) -> io::Result<UnixStream> {
345 self.0.duplicate().map(UnixStream)
346 }
347
348 /// Returns the socket address of the local half of this connection.
349 ///
350 /// # Examples
351 ///
352 /// ```no_run
353 /// use std::os::unix::net::UnixStream;
354 ///
355 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
356 /// let addr = socket.local_addr().expect("Couldn't get local address");
357 /// ```
358 #[stable(feature = "unix_socket", since = "1.10.0")]
359 pub fn local_addr(&self) -> io::Result<SocketAddr> {
360 SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
361 }
362
363 /// Returns the socket address of the remote half of this connection.
364 ///
365 /// # Examples
366 ///
367 /// ```no_run
368 /// use std::os::unix::net::UnixStream;
369 ///
370 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
371 /// let addr = socket.peer_addr().expect("Couldn't get peer address");
372 /// ```
373 #[stable(feature = "unix_socket", since = "1.10.0")]
374 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
375 SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
376 }
377
378 /// Sets the read timeout for the socket.
379 ///
380 /// If the provided value is [`None`], then [`read`] calls will block
381 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
382 /// method.
383 ///
384 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
385 /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
386 /// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read
387 /// [`Duration`]: ../../../../std/time/struct.Duration.html
388 ///
389 /// # Examples
390 ///
391 /// ```no_run
392 /// use std::os::unix::net::UnixStream;
393 /// use std::time::Duration;
394 ///
395 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
396 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
397 /// ```
398 ///
399 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
400 /// method:
401 ///
402 /// ```no_run
403 /// use std::io;
404 /// use std::os::unix::net::UnixStream;
405 /// use std::time::Duration;
406 ///
407 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
408 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
409 /// let err = result.unwrap_err();
410 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
411 /// ```
412 #[stable(feature = "unix_socket", since = "1.10.0")]
413 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
414 self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
415 }
416
417 /// Sets the write timeout for the socket.
418 ///
419 /// If the provided value is [`None`], then [`write`] calls will block
420 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
421 /// passed to this method.
422 ///
423 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
424 /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
425 /// [`write`]: ../../../../std/io/trait.Write.html#tymethod.write
426 /// [`Duration`]: ../../../../std/time/struct.Duration.html
427 ///
428 /// # Examples
429 ///
430 /// ```no_run
431 /// use std::os::unix::net::UnixStream;
432 /// use std::time::Duration;
433 ///
434 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
435 /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
436 /// ```
437 ///
438 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
439 /// method:
440 ///
441 /// ```no_run
442 /// use std::io;
443 /// use std::net::UdpSocket;
444 /// use std::time::Duration;
445 ///
446 /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
447 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
448 /// let err = result.unwrap_err();
449 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
450 /// ```
451 #[stable(feature = "unix_socket", since = "1.10.0")]
452 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
453 self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
454 }
455
456 /// Returns the read timeout of this socket.
457 ///
458 /// # Examples
459 ///
460 /// ```no_run
461 /// use std::os::unix::net::UnixStream;
462 /// use std::time::Duration;
463 ///
464 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
465 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
466 /// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0)));
467 /// ```
468 #[stable(feature = "unix_socket", since = "1.10.0")]
469 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
470 self.0.timeout(libc::SO_RCVTIMEO)
471 }
472
473 /// Returns the write timeout of this socket.
474 ///
475 /// # Examples
476 ///
477 /// ```no_run
478 /// use std::os::unix::net::UnixStream;
479 /// use std::time::Duration;
480 ///
481 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
482 /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
483 /// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0)));
484 /// ```
485 #[stable(feature = "unix_socket", since = "1.10.0")]
486 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
487 self.0.timeout(libc::SO_SNDTIMEO)
488 }
489
490 /// Moves the socket into or out of nonblocking mode.
491 ///
492 /// # Examples
493 ///
494 /// ```no_run
495 /// use std::os::unix::net::UnixStream;
496 ///
497 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
498 /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
499 /// ```
500 #[stable(feature = "unix_socket", since = "1.10.0")]
501 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
502 self.0.set_nonblocking(nonblocking)
503 }
504
505 /// Returns the value of the `SO_ERROR` option.
506 ///
507 /// # Examples
508 ///
509 /// ```no_run
510 /// use std::os::unix::net::UnixStream;
511 ///
512 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
513 /// if let Ok(Some(err)) = socket.take_error() {
514 /// println!("Got error: {:?}", err);
515 /// }
516 /// ```
517 ///
518 /// # Platform specific
519 /// On Redox this always returns `None`.
520 #[stable(feature = "unix_socket", since = "1.10.0")]
521 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
522 self.0.take_error()
523 }
524
525 /// Shuts down the read, write, or both halves of this connection.
526 ///
527 /// This function will cause all pending and future I/O calls on the
528 /// specified portions to immediately return with an appropriate value
529 /// (see the documentation of [`Shutdown`]).
530 ///
531 /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
532 ///
533 /// # Examples
534 ///
535 /// ```no_run
536 /// use std::os::unix::net::UnixStream;
537 /// use std::net::Shutdown;
538 ///
539 /// let socket = UnixStream::connect("/tmp/sock").unwrap();
540 /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
541 /// ```
542 #[stable(feature = "unix_socket", since = "1.10.0")]
543 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
544 self.0.shutdown(how)
545 }
546 }
547
548 #[stable(feature = "unix_socket", since = "1.10.0")]
549 impl io::Read for UnixStream {
550 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
551 io::Read::read(&mut &*self, buf)
552 }
553
554 fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
555 io::Read::read_vectored(&mut &*self, bufs)
556 }
557
558 #[inline]
559 unsafe fn initializer(&self) -> Initializer {
560 Initializer::nop()
561 }
562 }
563
564 #[stable(feature = "unix_socket", since = "1.10.0")]
565 impl<'a> io::Read for &'a UnixStream {
566 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
567 self.0.read(buf)
568 }
569
570 fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
571 self.0.read_vectored(bufs)
572 }
573
574 #[inline]
575 unsafe fn initializer(&self) -> Initializer {
576 Initializer::nop()
577 }
578 }
579
580 #[stable(feature = "unix_socket", since = "1.10.0")]
581 impl io::Write for UnixStream {
582 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
583 io::Write::write(&mut &*self, buf)
584 }
585
586 fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
587 io::Write::write_vectored(&mut &*self, bufs)
588 }
589
590 fn flush(&mut self) -> io::Result<()> {
591 io::Write::flush(&mut &*self)
592 }
593 }
594
595 #[stable(feature = "unix_socket", since = "1.10.0")]
596 impl<'a> io::Write for &'a UnixStream {
597 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
598 self.0.write(buf)
599 }
600
601 fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
602 self.0.write_vectored(bufs)
603 }
604
605 fn flush(&mut self) -> io::Result<()> {
606 Ok(())
607 }
608 }
609
610 #[stable(feature = "unix_socket", since = "1.10.0")]
611 impl AsRawFd for UnixStream {
612 fn as_raw_fd(&self) -> RawFd {
613 *self.0.as_inner()
614 }
615 }
616
617 #[stable(feature = "unix_socket", since = "1.10.0")]
618 impl FromRawFd for UnixStream {
619 unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
620 UnixStream(Socket::from_inner(fd))
621 }
622 }
623
624 #[stable(feature = "unix_socket", since = "1.10.0")]
625 impl IntoRawFd for UnixStream {
626 fn into_raw_fd(self) -> RawFd {
627 self.0.into_inner()
628 }
629 }
630
631 #[stable(feature = "rust1", since = "1.0.0")]
632 impl AsRawFd for net::TcpStream {
633 fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
634 }
635
636 #[stable(feature = "rust1", since = "1.0.0")]
637 impl AsRawFd for net::TcpListener {
638 fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
639 }
640
641 #[stable(feature = "rust1", since = "1.0.0")]
642 impl AsRawFd for net::UdpSocket {
643 fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
644 }
645
646 #[stable(feature = "from_raw_os", since = "1.1.0")]
647 impl FromRawFd for net::TcpStream {
648 unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
649 let socket = sys::net::Socket::from_inner(fd);
650 net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(socket))
651 }
652 }
653
654 #[stable(feature = "from_raw_os", since = "1.1.0")]
655 impl FromRawFd for net::TcpListener {
656 unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
657 let socket = sys::net::Socket::from_inner(fd);
658 net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(socket))
659 }
660 }
661
662 #[stable(feature = "from_raw_os", since = "1.1.0")]
663 impl FromRawFd for net::UdpSocket {
664 unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
665 let socket = sys::net::Socket::from_inner(fd);
666 net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(socket))
667 }
668 }
669
670 #[stable(feature = "into_raw_os", since = "1.4.0")]
671 impl IntoRawFd for net::TcpStream {
672 fn into_raw_fd(self) -> RawFd {
673 self.into_inner().into_socket().into_inner()
674 }
675 }
676 #[stable(feature = "into_raw_os", since = "1.4.0")]
677 impl IntoRawFd for net::TcpListener {
678 fn into_raw_fd(self) -> RawFd {
679 self.into_inner().into_socket().into_inner()
680 }
681 }
682 #[stable(feature = "into_raw_os", since = "1.4.0")]
683 impl IntoRawFd for net::UdpSocket {
684 fn into_raw_fd(self) -> RawFd {
685 self.into_inner().into_socket().into_inner()
686 }
687 }
688
689 /// A structure representing a Unix domain socket server.
690 ///
691 /// # Examples
692 ///
693 /// ```no_run
694 /// use std::thread;
695 /// use std::os::unix::net::{UnixStream, UnixListener};
696 ///
697 /// fn handle_client(stream: UnixStream) {
698 /// // ...
699 /// }
700 ///
701 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
702 ///
703 /// // accept connections and process them, spawning a new thread for each one
704 /// for stream in listener.incoming() {
705 /// match stream {
706 /// Ok(stream) => {
707 /// /* connection succeeded */
708 /// thread::spawn(|| handle_client(stream));
709 /// }
710 /// Err(err) => {
711 /// /* connection failed */
712 /// break;
713 /// }
714 /// }
715 /// }
716 /// ```
717 #[stable(feature = "unix_socket", since = "1.10.0")]
718 pub struct UnixListener(Socket);
719
720 #[stable(feature = "unix_socket", since = "1.10.0")]
721 impl fmt::Debug for UnixListener {
722 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
723 let mut builder = fmt.debug_struct("UnixListener");
724 builder.field("fd", self.0.as_inner());
725 if let Ok(addr) = self.local_addr() {
726 builder.field("local", &addr);
727 }
728 builder.finish()
729 }
730 }
731
732 impl UnixListener {
733 /// Creates a new `UnixListener` bound to the specified socket.
734 ///
735 /// # Examples
736 ///
737 /// ```no_run
738 /// use std::os::unix::net::UnixListener;
739 ///
740 /// let listener = match UnixListener::bind("/path/to/the/socket") {
741 /// Ok(sock) => sock,
742 /// Err(e) => {
743 /// println!("Couldn't connect: {:?}", e);
744 /// return
745 /// }
746 /// };
747 /// ```
748 #[stable(feature = "unix_socket", since = "1.10.0")]
749 pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
750 fn inner(path: &Path) -> io::Result<UnixListener> {
751 unsafe {
752 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
753 let (addr, len) = sockaddr_un(path)?;
754
755 cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len as _))?;
756 cvt(libc::listen(*inner.as_inner(), 128))?;
757
758 Ok(UnixListener(inner))
759 }
760 }
761 inner(path.as_ref())
762 }
763
764 /// Accepts a new incoming connection to this listener.
765 ///
766 /// This function will block the calling thread until a new Unix connection
767 /// is established. When established, the corresponding [`UnixStream`] and
768 /// the remote peer's address will be returned.
769 ///
770 /// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html
771 ///
772 /// # Examples
773 ///
774 /// ```no_run
775 /// use std::os::unix::net::UnixListener;
776 ///
777 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
778 ///
779 /// match listener.accept() {
780 /// Ok((socket, addr)) => println!("Got a client: {:?}", addr),
781 /// Err(e) => println!("accept function failed: {:?}", e),
782 /// }
783 /// ```
784 #[stable(feature = "unix_socket", since = "1.10.0")]
785 pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
786 let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() };
787 let mut len = mem::size_of_val(&storage) as libc::socklen_t;
788 let sock = self.0.accept(&mut storage as *mut _ as *mut _, &mut len)?;
789 let addr = SocketAddr::from_parts(storage, len)?;
790 Ok((UnixStream(sock), addr))
791 }
792
793 /// Creates a new independently owned handle to the underlying socket.
794 ///
795 /// The returned `UnixListener` is a reference to the same socket that this
796 /// object references. Both handles can be used to accept incoming
797 /// connections and options set on one listener will affect the other.
798 ///
799 /// # Examples
800 ///
801 /// ```no_run
802 /// use std::os::unix::net::UnixListener;
803 ///
804 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
805 ///
806 /// let listener_copy = listener.try_clone().expect("try_clone failed");
807 /// ```
808 #[stable(feature = "unix_socket", since = "1.10.0")]
809 pub fn try_clone(&self) -> io::Result<UnixListener> {
810 self.0.duplicate().map(UnixListener)
811 }
812
813 /// Returns the local socket address of this listener.
814 ///
815 /// # Examples
816 ///
817 /// ```no_run
818 /// use std::os::unix::net::UnixListener;
819 ///
820 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
821 ///
822 /// let addr = listener.local_addr().expect("Couldn't get local address");
823 /// ```
824 #[stable(feature = "unix_socket", since = "1.10.0")]
825 pub fn local_addr(&self) -> io::Result<SocketAddr> {
826 SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
827 }
828
829 /// Moves the socket into or out of nonblocking mode.
830 ///
831 /// # Examples
832 ///
833 /// ```no_run
834 /// use std::os::unix::net::UnixListener;
835 ///
836 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
837 ///
838 /// listener.set_nonblocking(true).expect("Couldn't set non blocking");
839 /// ```
840 #[stable(feature = "unix_socket", since = "1.10.0")]
841 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
842 self.0.set_nonblocking(nonblocking)
843 }
844
845 /// Returns the value of the `SO_ERROR` option.
846 ///
847 /// # Examples
848 ///
849 /// ```no_run
850 /// use std::os::unix::net::UnixListener;
851 ///
852 /// let listener = UnixListener::bind("/tmp/sock").unwrap();
853 ///
854 /// if let Ok(Some(err)) = listener.take_error() {
855 /// println!("Got error: {:?}", err);
856 /// }
857 /// ```
858 ///
859 /// # Platform specific
860 /// On Redox this always returns `None`.
861 #[stable(feature = "unix_socket", since = "1.10.0")]
862 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
863 self.0.take_error()
864 }
865
866 /// Returns an iterator over incoming connections.
867 ///
868 /// The iterator will never return [`None`] and will also not yield the
869 /// peer's [`SocketAddr`] structure.
870 ///
871 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
872 /// [`SocketAddr`]: struct.SocketAddr.html
873 ///
874 /// # Examples
875 ///
876 /// ```no_run
877 /// use std::thread;
878 /// use std::os::unix::net::{UnixStream, UnixListener};
879 ///
880 /// fn handle_client(stream: UnixStream) {
881 /// // ...
882 /// }
883 ///
884 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
885 ///
886 /// for stream in listener.incoming() {
887 /// match stream {
888 /// Ok(stream) => {
889 /// thread::spawn(|| handle_client(stream));
890 /// }
891 /// Err(err) => {
892 /// break;
893 /// }
894 /// }
895 /// }
896 /// ```
897 #[stable(feature = "unix_socket", since = "1.10.0")]
898 pub fn incoming<'a>(&'a self) -> Incoming<'a> {
899 Incoming { listener: self }
900 }
901 }
902
903 #[stable(feature = "unix_socket", since = "1.10.0")]
904 impl AsRawFd for UnixListener {
905 fn as_raw_fd(&self) -> RawFd {
906 *self.0.as_inner()
907 }
908 }
909
910 #[stable(feature = "unix_socket", since = "1.10.0")]
911 impl FromRawFd for UnixListener {
912 unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
913 UnixListener(Socket::from_inner(fd))
914 }
915 }
916
917 #[stable(feature = "unix_socket", since = "1.10.0")]
918 impl IntoRawFd for UnixListener {
919 fn into_raw_fd(self) -> RawFd {
920 self.0.into_inner()
921 }
922 }
923
924 #[stable(feature = "unix_socket", since = "1.10.0")]
925 impl<'a> IntoIterator for &'a UnixListener {
926 type Item = io::Result<UnixStream>;
927 type IntoIter = Incoming<'a>;
928
929 fn into_iter(self) -> Incoming<'a> {
930 self.incoming()
931 }
932 }
933
934 /// An iterator over incoming connections to a [`UnixListener`].
935 ///
936 /// It will never return [`None`].
937 ///
938 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
939 /// [`UnixListener`]: struct.UnixListener.html
940 ///
941 /// # Examples
942 ///
943 /// ```no_run
944 /// use std::thread;
945 /// use std::os::unix::net::{UnixStream, UnixListener};
946 ///
947 /// fn handle_client(stream: UnixStream) {
948 /// // ...
949 /// }
950 ///
951 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
952 ///
953 /// for stream in listener.incoming() {
954 /// match stream {
955 /// Ok(stream) => {
956 /// thread::spawn(|| handle_client(stream));
957 /// }
958 /// Err(err) => {
959 /// break;
960 /// }
961 /// }
962 /// }
963 /// ```
964 #[derive(Debug)]
965 #[stable(feature = "unix_socket", since = "1.10.0")]
966 pub struct Incoming<'a> {
967 listener: &'a UnixListener,
968 }
969
970 #[stable(feature = "unix_socket", since = "1.10.0")]
971 impl<'a> Iterator for Incoming<'a> {
972 type Item = io::Result<UnixStream>;
973
974 fn next(&mut self) -> Option<io::Result<UnixStream>> {
975 Some(self.listener.accept().map(|s| s.0))
976 }
977
978 fn size_hint(&self) -> (usize, Option<usize>) {
979 (usize::max_value(), None)
980 }
981 }
982
983 /// A Unix datagram socket.
984 ///
985 /// # Examples
986 ///
987 /// ```no_run
988 /// use std::os::unix::net::UnixDatagram;
989 ///
990 /// let socket = UnixDatagram::bind("/path/to/my/socket").unwrap();
991 /// socket.send_to(b"hello world", "/path/to/other/socket").unwrap();
992 /// let mut buf = [0; 100];
993 /// let (count, address) = socket.recv_from(&mut buf).unwrap();
994 /// println!("socket {:?} sent {:?}", address, &buf[..count]);
995 /// ```
996 #[stable(feature = "unix_socket", since = "1.10.0")]
997 pub struct UnixDatagram(Socket);
998
999 #[stable(feature = "unix_socket", since = "1.10.0")]
1000 impl fmt::Debug for UnixDatagram {
1001 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1002 let mut builder = fmt.debug_struct("UnixDatagram");
1003 builder.field("fd", self.0.as_inner());
1004 if let Ok(addr) = self.local_addr() {
1005 builder.field("local", &addr);
1006 }
1007 if let Ok(addr) = self.peer_addr() {
1008 builder.field("peer", &addr);
1009 }
1010 builder.finish()
1011 }
1012 }
1013
1014 impl UnixDatagram {
1015 /// Creates a Unix datagram socket bound to the given path.
1016 ///
1017 /// # Examples
1018 ///
1019 /// ```no_run
1020 /// use std::os::unix::net::UnixDatagram;
1021 ///
1022 /// let sock = match UnixDatagram::bind("/path/to/the/socket") {
1023 /// Ok(sock) => sock,
1024 /// Err(e) => {
1025 /// println!("Couldn't bind: {:?}", e);
1026 /// return
1027 /// }
1028 /// };
1029 /// ```
1030 #[stable(feature = "unix_socket", since = "1.10.0")]
1031 pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
1032 fn inner(path: &Path) -> io::Result<UnixDatagram> {
1033 unsafe {
1034 let socket = UnixDatagram::unbound()?;
1035 let (addr, len) = sockaddr_un(path)?;
1036
1037 cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len as _))?;
1038
1039 Ok(socket)
1040 }
1041 }
1042 inner(path.as_ref())
1043 }
1044
1045 /// Creates a Unix Datagram socket which is not bound to any address.
1046 ///
1047 /// # Examples
1048 ///
1049 /// ```no_run
1050 /// use std::os::unix::net::UnixDatagram;
1051 ///
1052 /// let sock = match UnixDatagram::unbound() {
1053 /// Ok(sock) => sock,
1054 /// Err(e) => {
1055 /// println!("Couldn't unbound: {:?}", e);
1056 /// return
1057 /// }
1058 /// };
1059 /// ```
1060 #[stable(feature = "unix_socket", since = "1.10.0")]
1061 pub fn unbound() -> io::Result<UnixDatagram> {
1062 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?;
1063 Ok(UnixDatagram(inner))
1064 }
1065
1066 /// Creates an unnamed pair of connected sockets.
1067 ///
1068 /// Returns two `UnixDatagrams`s which are connected to each other.
1069 ///
1070 /// # Examples
1071 ///
1072 /// ```no_run
1073 /// use std::os::unix::net::UnixDatagram;
1074 ///
1075 /// let (sock1, sock2) = match UnixDatagram::pair() {
1076 /// Ok((sock1, sock2)) => (sock1, sock2),
1077 /// Err(e) => {
1078 /// println!("Couldn't unbound: {:?}", e);
1079 /// return
1080 /// }
1081 /// };
1082 /// ```
1083 #[stable(feature = "unix_socket", since = "1.10.0")]
1084 pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
1085 let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?;
1086 Ok((UnixDatagram(i1), UnixDatagram(i2)))
1087 }
1088
1089 /// Connects the socket to the specified address.
1090 ///
1091 /// The [`send`] method may be used to send data to the specified address.
1092 /// [`recv`] and [`recv_from`] will only receive data from that address.
1093 ///
1094 /// [`send`]: #method.send
1095 /// [`recv`]: #method.recv
1096 /// [`recv_from`]: #method.recv_from
1097 ///
1098 /// # Examples
1099 ///
1100 /// ```no_run
1101 /// use std::os::unix::net::UnixDatagram;
1102 ///
1103 /// let sock = UnixDatagram::unbound().unwrap();
1104 /// match sock.connect("/path/to/the/socket") {
1105 /// Ok(sock) => sock,
1106 /// Err(e) => {
1107 /// println!("Couldn't connect: {:?}", e);
1108 /// return
1109 /// }
1110 /// };
1111 /// ```
1112 #[stable(feature = "unix_socket", since = "1.10.0")]
1113 pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
1114 fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> {
1115 unsafe {
1116 let (addr, len) = sockaddr_un(path)?;
1117
1118 cvt(libc::connect(*d.0.as_inner(), &addr as *const _ as *const _, len))?;
1119
1120 Ok(())
1121 }
1122 }
1123 inner(self, path.as_ref())
1124 }
1125
1126 /// Creates a new independently owned handle to the underlying socket.
1127 ///
1128 /// The returned `UnixDatagram` is a reference to the same socket that this
1129 /// object references. Both handles can be used to accept incoming
1130 /// connections and options set on one side will affect the other.
1131 ///
1132 /// # Examples
1133 ///
1134 /// ```no_run
1135 /// use std::os::unix::net::UnixDatagram;
1136 ///
1137 /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
1138 ///
1139 /// let sock_copy = sock.try_clone().expect("try_clone failed");
1140 /// ```
1141 #[stable(feature = "unix_socket", since = "1.10.0")]
1142 pub fn try_clone(&self) -> io::Result<UnixDatagram> {
1143 self.0.duplicate().map(UnixDatagram)
1144 }
1145
1146 /// Returns the address of this socket.
1147 ///
1148 /// # Examples
1149 ///
1150 /// ```no_run
1151 /// use std::os::unix::net::UnixDatagram;
1152 ///
1153 /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
1154 ///
1155 /// let addr = sock.local_addr().expect("Couldn't get local address");
1156 /// ```
1157 #[stable(feature = "unix_socket", since = "1.10.0")]
1158 pub fn local_addr(&self) -> io::Result<SocketAddr> {
1159 SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
1160 }
1161
1162 /// Returns the address of this socket's peer.
1163 ///
1164 /// The [`connect`] method will connect the socket to a peer.
1165 ///
1166 /// [`connect`]: #method.connect
1167 ///
1168 /// # Examples
1169 ///
1170 /// ```no_run
1171 /// use std::os::unix::net::UnixDatagram;
1172 ///
1173 /// let sock = UnixDatagram::unbound().unwrap();
1174 /// sock.connect("/path/to/the/socket").unwrap();
1175 ///
1176 /// let addr = sock.peer_addr().expect("Couldn't get peer address");
1177 /// ```
1178 #[stable(feature = "unix_socket", since = "1.10.0")]
1179 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
1180 SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
1181 }
1182
1183 /// Receives data from the socket.
1184 ///
1185 /// On success, returns the number of bytes read and the address from
1186 /// whence the data came.
1187 ///
1188 /// # Examples
1189 ///
1190 /// ```no_run
1191 /// use std::os::unix::net::UnixDatagram;
1192 ///
1193 /// let sock = UnixDatagram::unbound().unwrap();
1194 /// let mut buf = vec![0; 10];
1195 /// match sock.recv_from(buf.as_mut_slice()) {
1196 /// Ok((size, sender)) => println!("received {} bytes from {:?}", size, sender),
1197 /// Err(e) => println!("recv_from function failed: {:?}", e),
1198 /// }
1199 /// ```
1200 #[stable(feature = "unix_socket", since = "1.10.0")]
1201 pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
1202 let mut count = 0;
1203 let addr = SocketAddr::new(|addr, len| {
1204 unsafe {
1205 count = libc::recvfrom(*self.0.as_inner(),
1206 buf.as_mut_ptr() as *mut _,
1207 buf.len(),
1208 0,
1209 addr,
1210 len);
1211 if count > 0 {
1212 1
1213 } else if count == 0 {
1214 0
1215 } else {
1216 -1
1217 }
1218 }
1219 })?;
1220
1221 Ok((count as usize, addr))
1222 }
1223
1224 /// Receives data from the socket.
1225 ///
1226 /// On success, returns the number of bytes read.
1227 ///
1228 /// # Examples
1229 ///
1230 /// ```no_run
1231 /// use std::os::unix::net::UnixDatagram;
1232 ///
1233 /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
1234 /// let mut buf = vec![0; 10];
1235 /// sock.recv(buf.as_mut_slice()).expect("recv function failed");
1236 /// ```
1237 #[stable(feature = "unix_socket", since = "1.10.0")]
1238 pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
1239 self.0.read(buf)
1240 }
1241
1242 /// Sends data on the socket to the specified address.
1243 ///
1244 /// On success, returns the number of bytes written.
1245 ///
1246 /// # Examples
1247 ///
1248 /// ```no_run
1249 /// use std::os::unix::net::UnixDatagram;
1250 ///
1251 /// let sock = UnixDatagram::unbound().unwrap();
1252 /// sock.send_to(b"omelette au fromage", "/some/sock").expect("send_to function failed");
1253 /// ```
1254 #[stable(feature = "unix_socket", since = "1.10.0")]
1255 pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
1256 fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result<usize> {
1257 unsafe {
1258 let (addr, len) = sockaddr_un(path)?;
1259
1260 let count = cvt(libc::sendto(*d.0.as_inner(),
1261 buf.as_ptr() as *const _,
1262 buf.len(),
1263 MSG_NOSIGNAL,
1264 &addr as *const _ as *const _,
1265 len))?;
1266 Ok(count as usize)
1267 }
1268 }
1269 inner(self, buf, path.as_ref())
1270 }
1271
1272 /// Sends data on the socket to the socket's peer.
1273 ///
1274 /// The peer address may be set by the `connect` method, and this method
1275 /// will return an error if the socket has not already been connected.
1276 ///
1277 /// On success, returns the number of bytes written.
1278 ///
1279 /// # Examples
1280 ///
1281 /// ```no_run
1282 /// use std::os::unix::net::UnixDatagram;
1283 ///
1284 /// let sock = UnixDatagram::unbound().unwrap();
1285 /// sock.connect("/some/sock").expect("Couldn't connect");
1286 /// sock.send(b"omelette au fromage").expect("send_to function failed");
1287 /// ```
1288 #[stable(feature = "unix_socket", since = "1.10.0")]
1289 pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
1290 self.0.write(buf)
1291 }
1292
1293 /// Sets the read timeout for the socket.
1294 ///
1295 /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will
1296 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`]
1297 /// is passed to this method.
1298 ///
1299 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
1300 /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
1301 /// [`recv`]: #method.recv
1302 /// [`recv_from`]: #method.recv_from
1303 /// [`Duration`]: ../../../../std/time/struct.Duration.html
1304 ///
1305 /// # Examples
1306 ///
1307 /// ```
1308 /// use std::os::unix::net::UnixDatagram;
1309 /// use std::time::Duration;
1310 ///
1311 /// let sock = UnixDatagram::unbound().unwrap();
1312 /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed");
1313 /// ```
1314 ///
1315 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
1316 /// method:
1317 ///
1318 /// ```no_run
1319 /// use std::io;
1320 /// use std::os::unix::net::UnixDatagram;
1321 /// use std::time::Duration;
1322 ///
1323 /// let socket = UnixDatagram::unbound().unwrap();
1324 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
1325 /// let err = result.unwrap_err();
1326 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
1327 /// ```
1328 #[stable(feature = "unix_socket", since = "1.10.0")]
1329 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
1330 self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
1331 }
1332
1333 /// Sets the write timeout for the socket.
1334 ///
1335 /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will
1336 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
1337 /// method.
1338 ///
1339 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
1340 /// [`send`]: #method.send
1341 /// [`send_to`]: #method.send_to
1342 /// [`Duration`]: ../../../../std/time/struct.Duration.html
1343 ///
1344 /// # Examples
1345 ///
1346 /// ```
1347 /// use std::os::unix::net::UnixDatagram;
1348 /// use std::time::Duration;
1349 ///
1350 /// let sock = UnixDatagram::unbound().unwrap();
1351 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
1352 /// .expect("set_write_timeout function failed");
1353 /// ```
1354 ///
1355 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
1356 /// method:
1357 ///
1358 /// ```no_run
1359 /// use std::io;
1360 /// use std::os::unix::net::UnixDatagram;
1361 /// use std::time::Duration;
1362 ///
1363 /// let socket = UnixDatagram::unbound().unwrap();
1364 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
1365 /// let err = result.unwrap_err();
1366 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
1367 /// ```
1368 #[stable(feature = "unix_socket", since = "1.10.0")]
1369 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
1370 self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
1371 }
1372
1373 /// Returns the read timeout of this socket.
1374 ///
1375 /// # Examples
1376 ///
1377 /// ```
1378 /// use std::os::unix::net::UnixDatagram;
1379 /// use std::time::Duration;
1380 ///
1381 /// let sock = UnixDatagram::unbound().unwrap();
1382 /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed");
1383 /// assert_eq!(sock.read_timeout().unwrap(), Some(Duration::new(1, 0)));
1384 /// ```
1385 #[stable(feature = "unix_socket", since = "1.10.0")]
1386 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
1387 self.0.timeout(libc::SO_RCVTIMEO)
1388 }
1389
1390 /// Returns the write timeout of this socket.
1391 ///
1392 /// # Examples
1393 ///
1394 /// ```
1395 /// use std::os::unix::net::UnixDatagram;
1396 /// use std::time::Duration;
1397 ///
1398 /// let sock = UnixDatagram::unbound().unwrap();
1399 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
1400 /// .expect("set_write_timeout function failed");
1401 /// assert_eq!(sock.write_timeout().unwrap(), Some(Duration::new(1, 0)));
1402 /// ```
1403 #[stable(feature = "unix_socket", since = "1.10.0")]
1404 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
1405 self.0.timeout(libc::SO_SNDTIMEO)
1406 }
1407
1408 /// Moves the socket into or out of nonblocking mode.
1409 ///
1410 /// # Examples
1411 ///
1412 /// ```
1413 /// use std::os::unix::net::UnixDatagram;
1414 ///
1415 /// let sock = UnixDatagram::unbound().unwrap();
1416 /// sock.set_nonblocking(true).expect("set_nonblocking function failed");
1417 /// ```
1418 #[stable(feature = "unix_socket", since = "1.10.0")]
1419 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
1420 self.0.set_nonblocking(nonblocking)
1421 }
1422
1423 /// Returns the value of the `SO_ERROR` option.
1424 ///
1425 /// # Examples
1426 ///
1427 /// ```no_run
1428 /// use std::os::unix::net::UnixDatagram;
1429 ///
1430 /// let sock = UnixDatagram::unbound().unwrap();
1431 /// if let Ok(Some(err)) = sock.take_error() {
1432 /// println!("Got error: {:?}", err);
1433 /// }
1434 /// ```
1435 #[stable(feature = "unix_socket", since = "1.10.0")]
1436 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
1437 self.0.take_error()
1438 }
1439
1440 /// Shut down the read, write, or both halves of this connection.
1441 ///
1442 /// This function will cause all pending and future I/O calls on the
1443 /// specified portions to immediately return with an appropriate value
1444 /// (see the documentation of [`Shutdown`]).
1445 ///
1446 /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
1447 ///
1448 /// ```no_run
1449 /// use std::os::unix::net::UnixDatagram;
1450 /// use std::net::Shutdown;
1451 ///
1452 /// let sock = UnixDatagram::unbound().unwrap();
1453 /// sock.shutdown(Shutdown::Both).expect("shutdown function failed");
1454 /// ```
1455 #[stable(feature = "unix_socket", since = "1.10.0")]
1456 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
1457 self.0.shutdown(how)
1458 }
1459 }
1460
1461 #[stable(feature = "unix_socket", since = "1.10.0")]
1462 impl AsRawFd for UnixDatagram {
1463 fn as_raw_fd(&self) -> RawFd {
1464 *self.0.as_inner()
1465 }
1466 }
1467
1468 #[stable(feature = "unix_socket", since = "1.10.0")]
1469 impl FromRawFd for UnixDatagram {
1470 unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
1471 UnixDatagram(Socket::from_inner(fd))
1472 }
1473 }
1474
1475 #[stable(feature = "unix_socket", since = "1.10.0")]
1476 impl IntoRawFd for UnixDatagram {
1477 fn into_raw_fd(self) -> RawFd {
1478 self.0.into_inner()
1479 }
1480 }
1481
1482 #[cfg(all(test, not(target_os = "emscripten")))]
1483 mod test {
1484 use thread;
1485 use io::{self, ErrorKind};
1486 use io::prelude::*;
1487 use time::Duration;
1488 use sys_common::io::test::tmpdir;
1489
1490 use super::*;
1491
1492 macro_rules! or_panic {
1493 ($e:expr) => {
1494 match $e {
1495 Ok(e) => e,
1496 Err(e) => panic!("{}", e),
1497 }
1498 }
1499 }
1500
1501 #[test]
1502 fn basic() {
1503 let dir = tmpdir();
1504 let socket_path = dir.path().join("sock");
1505 let msg1 = b"hello";
1506 let msg2 = b"world!";
1507
1508 let listener = or_panic!(UnixListener::bind(&socket_path));
1509 let thread = thread::spawn(move || {
1510 let mut stream = or_panic!(listener.accept()).0;
1511 let mut buf = [0; 5];
1512 or_panic!(stream.read(&mut buf));
1513 assert_eq!(&msg1[..], &buf[..]);
1514 or_panic!(stream.write_all(msg2));
1515 });
1516
1517 let mut stream = or_panic!(UnixStream::connect(&socket_path));
1518 assert_eq!(Some(&*socket_path),
1519 stream.peer_addr().unwrap().as_pathname());
1520 or_panic!(stream.write_all(msg1));
1521 let mut buf = vec![];
1522 or_panic!(stream.read_to_end(&mut buf));
1523 assert_eq!(&msg2[..], &buf[..]);
1524 drop(stream);
1525
1526 thread.join().unwrap();
1527 }
1528
1529 #[test]
1530 fn vectored() {
1531 let (mut s1, mut s2) = or_panic!(UnixStream::pair());
1532
1533 let len = or_panic!(s1.write_vectored(
1534 &[IoVec::new(b"hello"), IoVec::new(b" "), IoVec::new(b"world!")],
1535 ));
1536 assert_eq!(len, 12);
1537
1538 let mut buf1 = [0; 6];
1539 let mut buf2 = [0; 7];
1540 let len = or_panic!(s2.read_vectored(
1541 &mut [IoVecMut::new(&mut buf1), IoVecMut::new(&mut buf2)],
1542 ));
1543 assert_eq!(len, 12);
1544 assert_eq!(&buf1, b"hello ");
1545 assert_eq!(&buf2, b"world!\0");
1546 }
1547
1548 #[test]
1549 fn pair() {
1550 let msg1 = b"hello";
1551 let msg2 = b"world!";
1552
1553 let (mut s1, mut s2) = or_panic!(UnixStream::pair());
1554 let thread = thread::spawn(move || {
1555 // s1 must be moved in or the test will hang!
1556 let mut buf = [0; 5];
1557 or_panic!(s1.read(&mut buf));
1558 assert_eq!(&msg1[..], &buf[..]);
1559 or_panic!(s1.write_all(msg2));
1560 });
1561
1562 or_panic!(s2.write_all(msg1));
1563 let mut buf = vec![];
1564 or_panic!(s2.read_to_end(&mut buf));
1565 assert_eq!(&msg2[..], &buf[..]);
1566 drop(s2);
1567
1568 thread.join().unwrap();
1569 }
1570
1571 #[test]
1572 fn try_clone() {
1573 let dir = tmpdir();
1574 let socket_path = dir.path().join("sock");
1575 let msg1 = b"hello";
1576 let msg2 = b"world";
1577
1578 let listener = or_panic!(UnixListener::bind(&socket_path));
1579 let thread = thread::spawn(move || {
1580 let mut stream = or_panic!(listener.accept()).0;
1581 or_panic!(stream.write_all(msg1));
1582 or_panic!(stream.write_all(msg2));
1583 });
1584
1585 let mut stream = or_panic!(UnixStream::connect(&socket_path));
1586 let mut stream2 = or_panic!(stream.try_clone());
1587
1588 let mut buf = [0; 5];
1589 or_panic!(stream.read(&mut buf));
1590 assert_eq!(&msg1[..], &buf[..]);
1591 or_panic!(stream2.read(&mut buf));
1592 assert_eq!(&msg2[..], &buf[..]);
1593
1594 thread.join().unwrap();
1595 }
1596
1597 #[test]
1598 fn iter() {
1599 let dir = tmpdir();
1600 let socket_path = dir.path().join("sock");
1601
1602 let listener = or_panic!(UnixListener::bind(&socket_path));
1603 let thread = thread::spawn(move || {
1604 for stream in listener.incoming().take(2) {
1605 let mut stream = or_panic!(stream);
1606 let mut buf = [0];
1607 or_panic!(stream.read(&mut buf));
1608 }
1609 });
1610
1611 for _ in 0..2 {
1612 let mut stream = or_panic!(UnixStream::connect(&socket_path));
1613 or_panic!(stream.write_all(&[0]));
1614 }
1615
1616 thread.join().unwrap();
1617 }
1618
1619 #[test]
1620 fn long_path() {
1621 let dir = tmpdir();
1622 let socket_path = dir.path()
1623 .join("asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\
1624 sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf");
1625 match UnixStream::connect(&socket_path) {
1626 Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
1627 Err(e) => panic!("unexpected error {}", e),
1628 Ok(_) => panic!("unexpected success"),
1629 }
1630
1631 match UnixListener::bind(&socket_path) {
1632 Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
1633 Err(e) => panic!("unexpected error {}", e),
1634 Ok(_) => panic!("unexpected success"),
1635 }
1636
1637 match UnixDatagram::bind(&socket_path) {
1638 Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
1639 Err(e) => panic!("unexpected error {}", e),
1640 Ok(_) => panic!("unexpected success"),
1641 }
1642 }
1643
1644 #[test]
1645 fn timeouts() {
1646 let dir = tmpdir();
1647 let socket_path = dir.path().join("sock");
1648
1649 let _listener = or_panic!(UnixListener::bind(&socket_path));
1650
1651 let stream = or_panic!(UnixStream::connect(&socket_path));
1652 let dur = Duration::new(15410, 0);
1653
1654 assert_eq!(None, or_panic!(stream.read_timeout()));
1655
1656 or_panic!(stream.set_read_timeout(Some(dur)));
1657 assert_eq!(Some(dur), or_panic!(stream.read_timeout()));
1658
1659 assert_eq!(None, or_panic!(stream.write_timeout()));
1660
1661 or_panic!(stream.set_write_timeout(Some(dur)));
1662 assert_eq!(Some(dur), or_panic!(stream.write_timeout()));
1663
1664 or_panic!(stream.set_read_timeout(None));
1665 assert_eq!(None, or_panic!(stream.read_timeout()));
1666
1667 or_panic!(stream.set_write_timeout(None));
1668 assert_eq!(None, or_panic!(stream.write_timeout()));
1669 }
1670
1671 #[test]
1672 fn test_read_timeout() {
1673 let dir = tmpdir();
1674 let socket_path = dir.path().join("sock");
1675
1676 let _listener = or_panic!(UnixListener::bind(&socket_path));
1677
1678 let mut stream = or_panic!(UnixStream::connect(&socket_path));
1679 or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
1680
1681 let mut buf = [0; 10];
1682 let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
1683 assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
1684 "unexpected_error: {:?}", kind);
1685 }
1686
1687 #[test]
1688 fn test_read_with_timeout() {
1689 let dir = tmpdir();
1690 let socket_path = dir.path().join("sock");
1691
1692 let listener = or_panic!(UnixListener::bind(&socket_path));
1693
1694 let mut stream = or_panic!(UnixStream::connect(&socket_path));
1695 or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
1696
1697 let mut other_end = or_panic!(listener.accept()).0;
1698 or_panic!(other_end.write_all(b"hello world"));
1699
1700 let mut buf = [0; 11];
1701 or_panic!(stream.read(&mut buf));
1702 assert_eq!(b"hello world", &buf[..]);
1703
1704 let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
1705 assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
1706 "unexpected_error: {:?}", kind);
1707 }
1708
1709 // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
1710 // when passed zero Durations
1711 #[test]
1712 fn test_unix_stream_timeout_zero_duration() {
1713 let dir = tmpdir();
1714 let socket_path = dir.path().join("sock");
1715
1716 let listener = or_panic!(UnixListener::bind(&socket_path));
1717 let stream = or_panic!(UnixStream::connect(&socket_path));
1718
1719 let result = stream.set_write_timeout(Some(Duration::new(0, 0)));
1720 let err = result.unwrap_err();
1721 assert_eq!(err.kind(), ErrorKind::InvalidInput);
1722
1723 let result = stream.set_read_timeout(Some(Duration::new(0, 0)));
1724 let err = result.unwrap_err();
1725 assert_eq!(err.kind(), ErrorKind::InvalidInput);
1726
1727 drop(listener);
1728 }
1729
1730 #[test]
1731 fn test_unix_datagram() {
1732 let dir = tmpdir();
1733 let path1 = dir.path().join("sock1");
1734 let path2 = dir.path().join("sock2");
1735
1736 let sock1 = or_panic!(UnixDatagram::bind(&path1));
1737 let sock2 = or_panic!(UnixDatagram::bind(&path2));
1738
1739 let msg = b"hello world";
1740 or_panic!(sock1.send_to(msg, &path2));
1741 let mut buf = [0; 11];
1742 or_panic!(sock2.recv_from(&mut buf));
1743 assert_eq!(msg, &buf[..]);
1744 }
1745
1746 #[test]
1747 fn test_unnamed_unix_datagram() {
1748 let dir = tmpdir();
1749 let path1 = dir.path().join("sock1");
1750
1751 let sock1 = or_panic!(UnixDatagram::bind(&path1));
1752 let sock2 = or_panic!(UnixDatagram::unbound());
1753
1754 let msg = b"hello world";
1755 or_panic!(sock2.send_to(msg, &path1));
1756 let mut buf = [0; 11];
1757 let (usize, addr) = or_panic!(sock1.recv_from(&mut buf));
1758 assert_eq!(usize, 11);
1759 assert!(addr.is_unnamed());
1760 assert_eq!(msg, &buf[..]);
1761 }
1762
1763 #[test]
1764 fn test_connect_unix_datagram() {
1765 let dir = tmpdir();
1766 let path1 = dir.path().join("sock1");
1767 let path2 = dir.path().join("sock2");
1768
1769 let bsock1 = or_panic!(UnixDatagram::bind(&path1));
1770 let bsock2 = or_panic!(UnixDatagram::bind(&path2));
1771 let sock = or_panic!(UnixDatagram::unbound());
1772 or_panic!(sock.connect(&path1));
1773
1774 // Check send()
1775 let msg = b"hello there";
1776 or_panic!(sock.send(msg));
1777 let mut buf = [0; 11];
1778 let (usize, addr) = or_panic!(bsock1.recv_from(&mut buf));
1779 assert_eq!(usize, 11);
1780 assert!(addr.is_unnamed());
1781 assert_eq!(msg, &buf[..]);
1782
1783 // Changing default socket works too
1784 or_panic!(sock.connect(&path2));
1785 or_panic!(sock.send(msg));
1786 or_panic!(bsock2.recv_from(&mut buf));
1787 }
1788
1789 #[test]
1790 fn test_unix_datagram_recv() {
1791 let dir = tmpdir();
1792 let path1 = dir.path().join("sock1");
1793
1794 let sock1 = or_panic!(UnixDatagram::bind(&path1));
1795 let sock2 = or_panic!(UnixDatagram::unbound());
1796 or_panic!(sock2.connect(&path1));
1797
1798 let msg = b"hello world";
1799 or_panic!(sock2.send(msg));
1800 let mut buf = [0; 11];
1801 let size = or_panic!(sock1.recv(&mut buf));
1802 assert_eq!(size, 11);
1803 assert_eq!(msg, &buf[..]);
1804 }
1805
1806 #[test]
1807 fn datagram_pair() {
1808 let msg1 = b"hello";
1809 let msg2 = b"world!";
1810
1811 let (s1, s2) = or_panic!(UnixDatagram::pair());
1812 let thread = thread::spawn(move || {
1813 // s1 must be moved in or the test will hang!
1814 let mut buf = [0; 5];
1815 or_panic!(s1.recv(&mut buf));
1816 assert_eq!(&msg1[..], &buf[..]);
1817 or_panic!(s1.send(msg2));
1818 });
1819
1820 or_panic!(s2.send(msg1));
1821 let mut buf = [0; 6];
1822 or_panic!(s2.recv(&mut buf));
1823 assert_eq!(&msg2[..], &buf[..]);
1824 drop(s2);
1825
1826 thread.join().unwrap();
1827 }
1828
1829 // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
1830 // when passed zero Durations
1831 #[test]
1832 fn test_unix_datagram_timeout_zero_duration() {
1833 let dir = tmpdir();
1834 let path = dir.path().join("sock");
1835
1836 let datagram = or_panic!(UnixDatagram::bind(&path));
1837
1838 let result = datagram.set_write_timeout(Some(Duration::new(0, 0)));
1839 let err = result.unwrap_err();
1840 assert_eq!(err.kind(), ErrorKind::InvalidInput);
1841
1842 let result = datagram.set_read_timeout(Some(Duration::new(0, 0)));
1843 let err = result.unwrap_err();
1844 assert_eq!(err.kind(), ErrorKind::InvalidInput);
1845 }
1846
1847 #[test]
1848 fn abstract_namespace_not_allowed() {
1849 assert!(UnixStream::connect("\0asdf").is_err());
1850 }
1851 }