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