]> git.proxmox.com Git - rustc.git/blame - 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
CommitLineData
1b1a35ee
XL
1//! Unix-specific networking functionality.
2
a7813a04 3#![stable(feature = "unix_socket", since = "1.10.0")]
54a0048b 4
1b1a35ee
XL
5#[cfg(all(test, not(target_os = "emscripten")))]
6mod tests;
54a0048b 7
3b2f2976
XL
8// FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here?
9#[cfg(not(unix))]
f9f354fc 10#[allow(non_camel_case_types)]
3b2f2976
XL
11mod 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
532ac7d7
XL
19use crate::ascii;
20use crate::ffi::OsStr;
21use crate::fmt;
48663c56 22use crate::io::{self, Initializer, IoSlice, IoSliceMut};
532ac7d7
XL
23use crate::mem;
24use crate::net::{self, Shutdown};
25use crate::os::unix::ffi::OsStrExt;
dfeec247 26use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
532ac7d7 27use crate::path::Path;
532ac7d7 28use crate::sys::net::Socket;
dfeec247 29use crate::sys::{self, cvt};
532ac7d7 30use crate::sys_common::{self, AsInner, FromInner, IntoInner};
dfeec247 31use crate::time::Duration;
54a0048b 32
1b1a35ee
XL
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))]
42use 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))]
54pub use ucred::UCred;
55
dfeec247
XL
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))]
c30ab7b3 65use libc::MSG_NOSIGNAL;
dfeec247
XL
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)))]
c30ab7b3
SL
75const MSG_NOSIGNAL: libc::c_int = 0x0;
76
dc9dc135 77fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
0531ce1d 78 // Work with an actual instance of the type since using a null pointer is UB
dc9dc135 79 let base = addr as *const _ as usize;
0531ce1d
XL
80 let path = &addr.sun_path as *const _ as usize;
81 path - base
54a0048b
SL
82}
83
84unsafe 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) {
dfeec247
XL
91 return Err(io::Error::new(
92 io::ErrorKind::InvalidInput,
93 "paths may not contain interior null bytes",
94 ));
54a0048b
SL
95 }
96
97 if bytes.len() >= addr.sun_path.len() {
dfeec247
XL
98 return Err(io::Error::new(
99 io::ErrorKind::InvalidInput,
100 "path must be shorter than SUN_LEN",
101 ));
54a0048b
SL
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
dc9dc135 109 let mut len = sun_path_offset(&addr) + bytes.len();
54a0048b
SL
110 match bytes.get(0) {
111 Some(&0) | None => {}
112 Some(_) => len += 1,
113 }
114 Ok((addr, len as libc::socklen_t))
115}
116
117enum AddressKind<'a> {
118 Unnamed,
119 Pathname(&'a Path),
120 Abstract(&'a [u8]),
121}
122
123/// An address associated with a Unix socket.
32a655c1
SL
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/// ```
54a0048b 139#[derive(Clone)]
a7813a04 140#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
141pub struct SocketAddr {
142 addr: libc::sockaddr_un,
143 len: libc::socklen_t,
144}
145
146impl SocketAddr {
147 fn new<F>(f: F) -> io::Result<SocketAddr>
dfeec247
XL
148 where
149 F: FnOnce(*mut libc::sockaddr, *mut libc::socklen_t) -> libc::c_int,
54a0048b
SL
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
dfeec247 163 len = sun_path_offset(&addr) as libc::socklen_t; // i.e., zero-length address
54a0048b 164 } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
dfeec247
XL
165 return Err(io::Error::new(
166 io::ErrorKind::InvalidInput,
167 "file descriptor did not correspond to a Unix socket",
168 ));
54a0048b
SL
169 }
170
dfeec247 171 Ok(SocketAddr { addr, len })
54a0048b
SL
172 }
173
9fa01778 174 /// Returns `true` if the address is unnamed.
32a655c1
SL
175 ///
176 /// # Examples
177 ///
178 /// A named address:
179 ///
180 /// ```no_run
181 /// use std::os::unix::net::UnixListener;
182 ///
60c5eb7d
XL
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 /// }
32a655c1
SL
189 /// ```
190 ///
191 /// An unnamed address:
192 ///
193 /// ```
194 /// use std::os::unix::net::UnixDatagram;
195 ///
60c5eb7d
XL
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 /// }
32a655c1 202 /// ```
a7813a04 203 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b 204 pub fn is_unnamed(&self) -> bool {
dfeec247 205 if let AddressKind::Unnamed = self.address() { true } else { false }
54a0048b
SL
206 }
207
208 /// Returns the contents of this address if it is a `pathname` address.
32a655c1
SL
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 ///
60c5eb7d
XL
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 /// }
32a655c1
SL
224 /// ```
225 ///
226 /// Without a pathname:
227 ///
228 /// ```
229 /// use std::os::unix::net::UnixDatagram;
230 ///
60c5eb7d
XL
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 /// }
32a655c1 237 /// ```
a7813a04 238 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b 239 pub fn as_pathname(&self) -> Option<&Path> {
dfeec247 240 if let AddressKind::Pathname(path) = self.address() { Some(path) } else { None }
54a0048b
SL
241 }
242
416331ca 243 fn address(&self) -> AddressKind<'_> {
dc9dc135 244 let len = self.len as usize - sun_path_offset(&self.addr);
54a0048b
SL
245 let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
246
cc61c64b 247 // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
83c7162d
XL
248 if len == 0
249 || (cfg!(not(any(target_os = "linux", target_os = "android")))
250 && self.addr.sun_path[0] == 0)
251 {
54a0048b
SL
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
a7813a04 261#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b 262impl fmt::Debug for SocketAddr {
532ac7d7 263 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
54a0048b
SL
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
272struct AsciiEscaped<'a>(&'a [u8]);
273
274impl<'a> fmt::Display for AsciiEscaped<'a> {
532ac7d7 275 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
54a0048b
SL
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///
32a655c1 288/// ```no_run
54a0048b
SL
289/// use std::os::unix::net::UnixStream;
290/// use std::io::prelude::*;
291///
60c5eb7d
XL
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/// }
54a0048b 300/// ```
a7813a04 301#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
302pub struct UnixStream(Socket);
303
a7813a04 304#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b 305impl fmt::Debug for UnixStream {
532ac7d7 306 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
54a0048b
SL
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
319impl UnixStream {
320 /// Connects to the socket named by `path`.
32a655c1
SL
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 /// ```
a7813a04 335 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
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 /// ```
a7813a04 366 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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
3b2f2976 376 /// data, and options set on one stream will be propagated to the other
54a0048b 377 /// stream.
32a655c1
SL
378 ///
379 /// # Examples
380 ///
381 /// ```no_run
382 /// use std::os::unix::net::UnixStream;
383 ///
60c5eb7d
XL
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 /// }
32a655c1 389 /// ```
a7813a04 390 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
396 ///
397 /// # Examples
398 ///
399 /// ```no_run
400 /// use std::os::unix::net::UnixStream;
401 ///
60c5eb7d
XL
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 /// }
32a655c1 407 /// ```
a7813a04 408 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
414 ///
415 /// # Examples
416 ///
417 /// ```no_run
418 /// use std::os::unix::net::UnixStream;
419 ///
60c5eb7d
XL
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 /// }
32a655c1 425 /// ```
a7813a04 426 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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
1b1a35ee
XL
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
54a0048b
SL
459 /// Sets the read timeout for the socket.
460 ///
cc61c64b 461 /// If the provided value is [`None`], then [`read`] calls will block
0531ce1d 462 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
54a0048b 463 /// method.
32a655c1 464 ///
3dfed10e 465 /// [`read`]: io::Read::read
32a655c1
SL
466 ///
467 /// # Examples
468 ///
469 /// ```no_run
470 /// use std::os::unix::net::UnixStream;
471 /// use std::time::Duration;
472 ///
60c5eb7d
XL
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 /// }
32a655c1 478 /// ```
0531ce1d
XL
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 ///
60c5eb7d
XL
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 /// }
0531ce1d 495 /// ```
a7813a04 496 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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 ///
cc61c64b 503 /// If the provided value is [`None`], then [`write`] calls will block
0531ce1d
XL
504 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
505 /// passed to this method.
32a655c1 506 ///
3dfed10e 507 /// [`read`]: io::Read::read
32a655c1
SL
508 ///
509 /// # Examples
510 ///
511 /// ```no_run
512 /// use std::os::unix::net::UnixStream;
513 /// use std::time::Duration;
514 ///
60c5eb7d
XL
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 /// }
32a655c1 521 /// ```
0531ce1d
XL
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 ///
60c5eb7d
XL
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 /// }
0531ce1d 538 /// ```
a7813a04 539 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
545 ///
546 /// # Examples
547 ///
548 /// ```no_run
549 /// use std::os::unix::net::UnixStream;
550 /// use std::time::Duration;
551 ///
60c5eb7d
XL
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 /// }
32a655c1 558 /// ```
a7813a04 559 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
565 ///
566 /// # Examples
567 ///
568 /// ```no_run
569 /// use std::os::unix::net::UnixStream;
570 /// use std::time::Duration;
571 ///
60c5eb7d
XL
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 /// }
32a655c1 579 /// ```
a7813a04 580 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
586 ///
587 /// # Examples
588 ///
589 /// ```no_run
590 /// use std::os::unix::net::UnixStream;
591 ///
60c5eb7d
XL
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 /// }
32a655c1 597 /// ```
a7813a04 598 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
604 ///
605 /// # Examples
606 ///
607 /// ```no_run
608 /// use std::os::unix::net::UnixStream;
609 ///
60c5eb7d
XL
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(())
32a655c1
SL
616 /// }
617 /// ```
8faf50e0
XL
618 ///
619 /// # Platform specific
9fa01778 620 /// On Redox this always returns `None`.
a7813a04 621 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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
32a655c1
SL
630 /// (see the documentation of [`Shutdown`]).
631 ///
32a655c1
SL
632 /// # Examples
633 ///
634 /// ```no_run
635 /// use std::os::unix::net::UnixStream;
636 /// use std::net::Shutdown;
637 ///
60c5eb7d
XL
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 /// }
32a655c1 643 /// ```
a7813a04 644 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
645 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
646 self.0.shutdown(how)
647 }
1b1a35ee
XL
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 }
54a0048b
SL
674}
675
a7813a04 676#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
677impl io::Read for UnixStream {
678 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
679 io::Read::read(&mut &*self, buf)
680 }
681
48663c56 682 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
9fa01778
XL
683 io::Read::read_vectored(&mut &*self, bufs)
684 }
685
f9f354fc
XL
686 #[inline]
687 fn is_read_vectored(&self) -> bool {
688 io::Read::is_read_vectored(&&*self)
689 }
690
041b39d2
XL
691 #[inline]
692 unsafe fn initializer(&self) -> Initializer {
693 Initializer::nop()
54a0048b
SL
694 }
695}
696
a7813a04 697#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
698impl<'a> io::Read for &'a UnixStream {
699 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
700 self.0.read(buf)
701 }
702
48663c56 703 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
9fa01778
XL
704 self.0.read_vectored(bufs)
705 }
706
f9f354fc
XL
707 #[inline]
708 fn is_read_vectored(&self) -> bool {
709 self.0.is_read_vectored()
710 }
711
041b39d2
XL
712 #[inline]
713 unsafe fn initializer(&self) -> Initializer {
714 Initializer::nop()
54a0048b
SL
715 }
716}
717
a7813a04 718#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
719impl io::Write for UnixStream {
720 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
721 io::Write::write(&mut &*self, buf)
722 }
723
48663c56 724 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
9fa01778
XL
725 io::Write::write_vectored(&mut &*self, bufs)
726 }
727
f9f354fc
XL
728 #[inline]
729 fn is_write_vectored(&self) -> bool {
730 io::Write::is_write_vectored(&&*self)
731 }
732
54a0048b
SL
733 fn flush(&mut self) -> io::Result<()> {
734 io::Write::flush(&mut &*self)
735 }
736}
737
a7813a04 738#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
739impl<'a> io::Write for &'a UnixStream {
740 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
741 self.0.write(buf)
742 }
743
48663c56 744 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
9fa01778
XL
745 self.0.write_vectored(bufs)
746 }
747
f9f354fc
XL
748 #[inline]
749 fn is_write_vectored(&self) -> bool {
750 self.0.is_write_vectored()
751 }
752
54a0048b
SL
753 fn flush(&mut self) -> io::Result<()> {
754 Ok(())
755 }
756}
757
a7813a04 758#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
759impl AsRawFd for UnixStream {
760 fn as_raw_fd(&self) -> RawFd {
761 *self.0.as_inner()
762 }
763}
764
a7813a04 765#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
766impl FromRawFd for UnixStream {
767 unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
768 UnixStream(Socket::from_inner(fd))
769 }
770}
771
a7813a04 772#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
773impl IntoRawFd for UnixStream {
774 fn into_raw_fd(self) -> RawFd {
775 self.0.into_inner()
776 }
777}
778
3b2f2976
XL
779#[stable(feature = "rust1", since = "1.0.0")]
780impl AsRawFd for net::TcpStream {
dfeec247
XL
781 fn as_raw_fd(&self) -> RawFd {
782 *self.as_inner().socket().as_inner()
783 }
3b2f2976
XL
784}
785
786#[stable(feature = "rust1", since = "1.0.0")]
787impl AsRawFd for net::TcpListener {
dfeec247
XL
788 fn as_raw_fd(&self) -> RawFd {
789 *self.as_inner().socket().as_inner()
790 }
3b2f2976
XL
791}
792
793#[stable(feature = "rust1", since = "1.0.0")]
794impl AsRawFd for net::UdpSocket {
dfeec247
XL
795 fn as_raw_fd(&self) -> RawFd {
796 *self.as_inner().socket().as_inner()
797 }
3b2f2976
XL
798}
799
800#[stable(feature = "from_raw_os", since = "1.1.0")]
801impl 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")]
809impl 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")]
817impl 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")]
825impl 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")]
831impl 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")]
837impl IntoRawFd for net::UdpSocket {
838 fn into_raw_fd(self) -> RawFd {
839 self.into_inner().into_socket().into_inner()
840 }
841}
842
54a0048b
SL
843/// A structure representing a Unix domain socket server.
844///
845/// # Examples
846///
32a655c1 847/// ```no_run
54a0048b
SL
848/// use std::thread;
849/// use std::os::unix::net::{UnixStream, UnixListener};
850///
851/// fn handle_client(stream: UnixStream) {
852/// // ...
853/// }
854///
60c5eb7d
XL
855/// fn main() -> std::io::Result<()> {
856/// let listener = UnixListener::bind("/path/to/the/socket")?;
54a0048b 857///
60c5eb7d
XL
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/// }
54a0048b
SL
869/// }
870/// }
60c5eb7d 871/// Ok(())
54a0048b 872/// }
54a0048b 873/// ```
a7813a04 874#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
875pub struct UnixListener(Socket);
876
a7813a04 877#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b 878impl fmt::Debug for UnixListener {
532ac7d7 879 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
54a0048b
SL
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
889impl UnixListener {
890 /// Creates a new `UnixListener` bound to the specified socket.
32a655c1
SL
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 /// ```
a7813a04 905 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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
cc61c64b 912 cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len as _))?;
54a0048b
SL
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
3b2f2976 924 /// is established. When established, the corresponding [`UnixStream`] and
54a0048b 925 /// the remote peer's address will be returned.
32a655c1 926 ///
3dfed10e 927 /// [`UnixStream`]: crate::os::unix::net::UnixStream
32a655c1
SL
928 ///
929 /// # Examples
930 ///
931 /// ```no_run
932 /// use std::os::unix::net::UnixListener;
933 ///
60c5eb7d
XL
934 /// fn main() -> std::io::Result<()> {
935 /// let listener = UnixListener::bind("/path/to/the/socket")?;
32a655c1 936 ///
60c5eb7d
XL
937 /// match listener.accept() {
938 /// Ok((socket, addr)) => println!("Got a client: {:?}", addr),
939 /// Err(e) => println!("accept function failed: {:?}", e),
940 /// }
941 /// Ok(())
32a655c1
SL
942 /// }
943 /// ```
a7813a04 944 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
958 ///
959 /// # Examples
960 ///
961 /// ```no_run
962 /// use std::os::unix::net::UnixListener;
963 ///
60c5eb7d
XL
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 /// }
32a655c1 969 /// ```
a7813a04 970 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
976 ///
977 /// # Examples
978 ///
979 /// ```no_run
980 /// use std::os::unix::net::UnixListener;
981 ///
60c5eb7d
XL
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 /// }
32a655c1 987 /// ```
a7813a04 988 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1 994 ///
dfeec247
XL
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 ///
32a655c1
SL
1001 /// # Examples
1002 ///
1003 /// ```no_run
1004 /// use std::os::unix::net::UnixListener;
1005 ///
60c5eb7d
XL
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 /// }
32a655c1 1011 /// ```
a7813a04 1012 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
1018 ///
1019 /// # Examples
1020 ///
1021 /// ```no_run
1022 /// use std::os::unix::net::UnixListener;
1023 ///
60c5eb7d
XL
1024 /// fn main() -> std::io::Result<()> {
1025 /// let listener = UnixListener::bind("/tmp/sock")?;
32a655c1 1026 ///
60c5eb7d
XL
1027 /// if let Ok(Some(err)) = listener.take_error() {
1028 /// println!("Got error: {:?}", err);
1029 /// }
1030 /// Ok(())
32a655c1
SL
1031 /// }
1032 /// ```
8faf50e0
XL
1033 ///
1034 /// # Platform specific
9fa01778 1035 /// On Redox this always returns `None`.
a7813a04 1036 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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 ///
32a655c1
SL
1043 /// The iterator will never return [`None`] and will also not yield the
1044 /// peer's [`SocketAddr`] structure.
1045 ///
32a655c1
SL
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 ///
60c5eb7d
XL
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 /// }
32a655c1
SL
1067 /// }
1068 /// }
60c5eb7d 1069 /// Ok(())
32a655c1
SL
1070 /// }
1071 /// ```
a7813a04 1072 #[stable(feature = "unix_socket", since = "1.10.0")]
416331ca 1073 pub fn incoming(&self) -> Incoming<'_> {
54a0048b
SL
1074 Incoming { listener: self }
1075 }
1076}
1077
a7813a04 1078#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
1079impl AsRawFd for UnixListener {
1080 fn as_raw_fd(&self) -> RawFd {
1081 *self.0.as_inner()
1082 }
1083}
1084
a7813a04 1085#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
1086impl FromRawFd for UnixListener {
1087 unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
1088 UnixListener(Socket::from_inner(fd))
1089 }
1090}
1091
a7813a04 1092#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
1093impl IntoRawFd for UnixListener {
1094 fn into_raw_fd(self) -> RawFd {
1095 self.0.into_inner()
1096 }
1097}
1098
a7813a04 1099#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
1100impl<'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
32a655c1
SL
1109/// An iterator over incoming connections to a [`UnixListener`].
1110///
1111/// It will never return [`None`].
1112///
32a655c1 1113/// # Examples
54a0048b 1114///
32a655c1
SL
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///
60c5eb7d
XL
1123/// fn main() -> std::io::Result<()> {
1124/// let listener = UnixListener::bind("/path/to/the/socket")?;
32a655c1 1125///
60c5eb7d
XL
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/// }
32a655c1
SL
1134/// }
1135/// }
60c5eb7d 1136/// Ok(())
32a655c1
SL
1137/// }
1138/// ```
54a0048b 1139#[derive(Debug)]
a7813a04 1140#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
1141pub struct Incoming<'a> {
1142 listener: &'a UnixListener,
1143}
1144
a7813a04 1145#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
1146impl<'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>) {
f035d41b 1154 (usize::MAX, None)
54a0048b
SL
1155 }
1156}
1157
1158/// A Unix datagram socket.
1159///
1160/// # Examples
1161///
32a655c1 1162/// ```no_run
54a0048b
SL
1163/// use std::os::unix::net::UnixDatagram;
1164///
60c5eb7d
XL
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/// }
54a0048b 1173/// ```
a7813a04 1174#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
1175pub struct UnixDatagram(Socket);
1176
a7813a04 1177#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b 1178impl fmt::Debug for UnixDatagram {
532ac7d7 1179 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
54a0048b
SL
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
1192impl UnixDatagram {
1193 /// Creates a Unix datagram socket bound to the given path.
32a655c1
SL
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 /// ```
a7813a04 1208 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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
cc61c64b 1215 cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len as _))?;
54a0048b
SL
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.
32a655c1
SL
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 /// ```
a7813a04 1238 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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
9fa01778 1244 /// Creates an unnamed pair of connected sockets.
54a0048b
SL
1245 ///
1246 /// Returns two `UnixDatagrams`s which are connected to each other.
32a655c1
SL
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 /// ```
a7813a04 1261 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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 ///
cc61c64b
XL
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.
32a655c1 1271 ///
3dfed10e
XL
1272 /// [`send`]: UnixDatagram::send
1273 /// [`recv`]: UnixDatagram::recv
1274 /// [`recv_from`]: UnixDatagram::recv_from
32a655c1
SL
1275 ///
1276 /// # Examples
1277 ///
1278 /// ```no_run
1279 /// use std::os::unix::net::UnixDatagram;
1280 ///
60c5eb7d
XL
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 /// }
32a655c1 1292 /// ```
a7813a04 1293 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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 ///
32a655c1 1309 /// The returned `UnixDatagram` is a reference to the same socket that this
54a0048b 1310 /// object references. Both handles can be used to accept incoming
32a655c1
SL
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 ///
60c5eb7d
XL
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 /// }
32a655c1 1323 /// ```
a7813a04 1324 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
1325 pub fn try_clone(&self) -> io::Result<UnixDatagram> {
1326 self.0.duplicate().map(UnixDatagram)
1327 }
1328
1329 /// Returns the address of this socket.
32a655c1
SL
1330 ///
1331 /// # Examples
1332 ///
1333 /// ```no_run
1334 /// use std::os::unix::net::UnixDatagram;
1335 ///
60c5eb7d
XL
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 /// }
32a655c1 1341 /// ```
a7813a04 1342 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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 ///
cc61c64b 1349 /// The [`connect`] method will connect the socket to a peer.
32a655c1 1350 ///
3dfed10e 1351 /// [`connect`]: UnixDatagram::connect
32a655c1
SL
1352 ///
1353 /// # Examples
1354 ///
1355 /// ```no_run
1356 /// use std::os::unix::net::UnixDatagram;
1357 ///
60c5eb7d
XL
1358 /// fn main() -> std::io::Result<()> {
1359 /// let sock = UnixDatagram::unbound()?;
1360 /// sock.connect("/path/to/the/socket")?;
32a655c1 1361 ///
60c5eb7d
XL
1362 /// let addr = sock.peer_addr().expect("Couldn't get peer address");
1363 /// Ok(())
1364 /// }
32a655c1 1365 /// ```
a7813a04 1366 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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
1b1a35ee
XL
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
54a0048b
SL
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.
32a655c1
SL
1402 ///
1403 /// # Examples
1404 ///
1405 /// ```no_run
1406 /// use std::os::unix::net::UnixDatagram;
1407 ///
60c5eb7d
XL
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(())
32a655c1
SL
1414 /// }
1415 /// ```
a7813a04 1416 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b 1417 pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
1b1a35ee 1418 self.recv_from_flags(buf, 0)
54a0048b
SL
1419 }
1420
1421 /// Receives data from the socket.
1422 ///
1423 /// On success, returns the number of bytes read.
32a655c1
SL
1424 ///
1425 /// # Examples
1426 ///
1427 /// ```no_run
1428 /// use std::os::unix::net::UnixDatagram;
1429 ///
60c5eb7d
XL
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 /// }
32a655c1 1436 /// ```
a7813a04 1437 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
1445 ///
1446 /// # Examples
1447 ///
1448 /// ```no_run
1449 /// use std::os::unix::net::UnixDatagram;
1450 ///
60c5eb7d
XL
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 /// }
32a655c1 1456 /// ```
a7813a04 1457 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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
dfeec247
XL
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 ))?;
54a0048b
SL
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.
32a655c1
SL
1483 ///
1484 /// # Examples
1485 ///
1486 /// ```no_run
1487 /// use std::os::unix::net::UnixDatagram;
1488 ///
60c5eb7d
XL
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 /// }
32a655c1 1495 /// ```
a7813a04 1496 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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 ///
cc61c64b 1503 /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will
0531ce1d
XL
1504 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`]
1505 /// is passed to this method.
32a655c1 1506 ///
3dfed10e
XL
1507 /// [`recv`]: UnixDatagram::recv
1508 /// [`recv_from`]: UnixDatagram::recv_from
32a655c1
SL
1509 ///
1510 /// # Examples
1511 ///
1512 /// ```
1513 /// use std::os::unix::net::UnixDatagram;
1514 /// use std::time::Duration;
1515 ///
60c5eb7d
XL
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 /// }
32a655c1 1522 /// ```
0531ce1d
XL
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 ///
60c5eb7d
XL
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 /// }
0531ce1d 1539 /// ```
a7813a04 1540 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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 ///
cc61c64b 1547 /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will
0531ce1d 1548 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
54a0048b 1549 /// method.
32a655c1 1550 ///
3dfed10e
XL
1551 /// [`send`]: UnixDatagram::send
1552 /// [`send_to`]: UnixDatagram::send_to
32a655c1
SL
1553 ///
1554 /// # Examples
1555 ///
1556 /// ```
1557 /// use std::os::unix::net::UnixDatagram;
1558 /// use std::time::Duration;
1559 ///
60c5eb7d
XL
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 /// }
32a655c1 1566 /// ```
0531ce1d
XL
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 ///
60c5eb7d
XL
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 /// }
0531ce1d 1583 /// ```
a7813a04 1584 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
1590 ///
1591 /// # Examples
1592 ///
1593 /// ```
1594 /// use std::os::unix::net::UnixDatagram;
1595 /// use std::time::Duration;
1596 ///
60c5eb7d
XL
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 /// }
32a655c1 1604 /// ```
a7813a04 1605 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
1611 ///
1612 /// # Examples
1613 ///
1614 /// ```
1615 /// use std::os::unix::net::UnixDatagram;
1616 /// use std::time::Duration;
1617 ///
60c5eb7d
XL
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 /// }
32a655c1 1625 /// ```
a7813a04 1626 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
1632 ///
1633 /// # Examples
1634 ///
1635 /// ```
1636 /// use std::os::unix::net::UnixDatagram;
1637 ///
60c5eb7d
XL
1638 /// fn main() -> std::io::Result<()> {
1639 /// let sock = UnixDatagram::unbound()?;
1640 /// sock.set_nonblocking(true).expect("set_nonblocking function failed");
1641 /// Ok(())
1642 /// }
32a655c1 1643 /// ```
a7813a04 1644 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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.
32a655c1
SL
1650 ///
1651 /// # Examples
1652 ///
1653 /// ```no_run
1654 /// use std::os::unix::net::UnixDatagram;
1655 ///
60c5eb7d
XL
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(())
32a655c1
SL
1662 /// }
1663 /// ```
a7813a04 1664 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
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
32a655c1
SL
1673 /// (see the documentation of [`Shutdown`]).
1674 ///
32a655c1
SL
1675 /// ```no_run
1676 /// use std::os::unix::net::UnixDatagram;
1677 /// use std::net::Shutdown;
1678 ///
60c5eb7d
XL
1679 /// fn main() -> std::io::Result<()> {
1680 /// let sock = UnixDatagram::unbound()?;
1681 /// sock.shutdown(Shutdown::Both).expect("shutdown function failed");
1682 /// Ok(())
1683 /// }
32a655c1 1684 /// ```
a7813a04 1685 #[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
1686 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
1687 self.0.shutdown(how)
1688 }
1b1a35ee
XL
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 }
54a0048b
SL
1747}
1748
a7813a04 1749#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
1750impl AsRawFd for UnixDatagram {
1751 fn as_raw_fd(&self) -> RawFd {
1752 *self.0.as_inner()
1753 }
1754}
1755
a7813a04 1756#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
1757impl FromRawFd for UnixDatagram {
1758 unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
1759 UnixDatagram(Socket::from_inner(fd))
1760 }
1761}
1762
a7813a04 1763#[stable(feature = "unix_socket", since = "1.10.0")]
54a0048b
SL
1764impl IntoRawFd for UnixDatagram {
1765 fn into_raw_fd(self) -> RawFd {
1766 self.0.into_inner()
1767 }
1768}