std/os/unix/net/datagram.rs
1#[cfg(any(
2 target_os = "linux",
3 target_os = "android",
4 target_os = "dragonfly",
5 target_os = "freebsd",
6 target_os = "openbsd",
7 target_os = "netbsd",
8 target_os = "solaris",
9 target_os = "illumos",
10 target_os = "haiku",
11 target_os = "nto",
12 target_os = "qnx",
13 target_os = "cygwin"
14))]
15use libc::MSG_NOSIGNAL;
16
17use super::{SocketAddr, sockaddr_un};
18#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
19use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to};
20#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
21use crate::io::{IoSlice, IoSliceMut};
22use crate::net::Shutdown;
23use crate::os::unix::io::{
24 AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd, unsafe_impl_fd_asrefs,
25};
26use crate::path::Path;
27use crate::sys::net::Socket;
28use crate::sys::{AsInner, FromInner, IntoInner, cvt};
29use crate::time::Duration;
30use crate::{fmt, io};
31#[cfg(not(any(
32 target_os = "linux",
33 target_os = "android",
34 target_os = "dragonfly",
35 target_os = "freebsd",
36 target_os = "openbsd",
37 target_os = "netbsd",
38 target_os = "solaris",
39 target_os = "illumos",
40 target_os = "haiku",
41 target_os = "nto",
42 target_os = "qnx",
43 target_os = "cygwin"
44)))]
45const MSG_NOSIGNAL: core::ffi::c_int = 0x0;
46
47/// A Unix datagram socket.
48///
49/// # Examples
50///
51#[cfg_attr(target_family = "unix", doc = "```no_run")]
52#[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
53/// use std::os::unix::net::UnixDatagram;
54///
55/// fn main() -> std::io::Result<()> {
56/// let socket = UnixDatagram::bind("/path/to/my/socket")?;
57/// socket.send_to(b"hello world", "/path/to/other/socket")?;
58/// let mut buf = [0; 100];
59/// let (count, address) = socket.recv_from(&mut buf)?;
60/// println!("socket {:?} sent {:?}", address, &buf[..count]);
61/// Ok(())
62/// }
63/// ```
64#[stable(feature = "unix_socket", since = "1.10.0")]
65pub struct UnixDatagram(Socket);
66
67#[stable(feature = "unix_socket", since = "1.10.0")]
68impl fmt::Debug for UnixDatagram {
69 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
70 let mut builder = fmt.debug_struct("UnixDatagram");
71 builder.field("fd", self.0.as_inner());
72 if let Ok(addr) = self.local_addr() {
73 builder.field("local", &addr);
74 }
75 if let Ok(addr) = self.peer_addr() {
76 builder.field("peer", &addr);
77 }
78 builder.finish()
79 }
80}
81
82impl UnixDatagram {
83 /// Creates a Unix datagram socket bound to the given path.
84 ///
85 /// # Examples
86 ///
87 #[cfg_attr(target_family = "unix", doc = "```no_run")]
88 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
89 /// use std::os::unix::net::UnixDatagram;
90 ///
91 /// let sock = match UnixDatagram::bind("/path/to/the/socket") {
92 /// Ok(sock) => sock,
93 /// Err(e) => {
94 /// println!("Couldn't bind: {e:?}");
95 /// return
96 /// }
97 /// };
98 /// ```
99 #[stable(feature = "unix_socket", since = "1.10.0")]
100 pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
101 unsafe {
102 let socket = UnixDatagram::unbound()?;
103 let (addr, len) = sockaddr_un(path.as_ref())?;
104
105 cvt(libc::bind(socket.as_raw_fd(), (&raw const addr) as *const _, len as _))?;
106
107 Ok(socket)
108 }
109 }
110
111 /// Creates a Unix datagram socket bound to an address.
112 ///
113 /// # Examples
114 ///
115 #[cfg_attr(target_family = "unix", doc = "```no_run")]
116 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
117 /// use std::os::unix::net::{SocketAddr, UnixDatagram};
118 ///
119 /// fn main() -> std::io::Result<()> {
120 /// let addr = SocketAddr::from_pathname("path/to/socket")?;
121 ///
122 /// let sock = match UnixDatagram::bind_addr(&addr) {
123 /// Ok(sock) => sock,
124 /// Err(err) => {
125 /// println!("Couldn't bind: {err:?}");
126 /// return Err(err);
127 /// }
128 /// };
129 /// Ok(())
130 /// }
131 /// ```
132 #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
133 pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result<UnixDatagram> {
134 unsafe {
135 let socket = UnixDatagram::unbound()?;
136 cvt(libc::bind(
137 socket.as_raw_fd(),
138 (&raw const socket_addr.addr) as *const _,
139 socket_addr.len as _,
140 ))?;
141 Ok(socket)
142 }
143 }
144
145 /// Creates a Unix Datagram socket which is not bound to any address.
146 ///
147 /// # Examples
148 ///
149 #[cfg_attr(target_family = "unix", doc = "```no_run")]
150 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
151 /// use std::os::unix::net::UnixDatagram;
152 ///
153 /// let sock = match UnixDatagram::unbound() {
154 /// Ok(sock) => sock,
155 /// Err(e) => {
156 /// println!("Couldn't unbound: {e:?}");
157 /// return
158 /// }
159 /// };
160 /// ```
161 #[stable(feature = "unix_socket", since = "1.10.0")]
162 pub fn unbound() -> io::Result<UnixDatagram> {
163 let inner = Socket::new(libc::AF_UNIX, libc::SOCK_DGRAM)?;
164 Ok(UnixDatagram(inner))
165 }
166
167 /// Creates an unnamed pair of connected sockets.
168 ///
169 /// Returns two `UnixDatagrams`s which are connected to each other.
170 ///
171 /// # Examples
172 ///
173 #[cfg_attr(target_family = "unix", doc = "```no_run")]
174 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
175 /// use std::os::unix::net::UnixDatagram;
176 ///
177 /// let (sock1, sock2) = match UnixDatagram::pair() {
178 /// Ok((sock1, sock2)) => (sock1, sock2),
179 /// Err(e) => {
180 /// println!("Couldn't unbound: {e:?}");
181 /// return
182 /// }
183 /// };
184 /// ```
185 #[stable(feature = "unix_socket", since = "1.10.0")]
186 pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
187 let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?;
188 Ok((UnixDatagram(i1), UnixDatagram(i2)))
189 }
190
191 /// Connects the socket to the specified path address.
192 ///
193 /// The [`send`] method may be used to send data to the specified address.
194 /// [`recv`] and [`recv_from`] will only receive data from that address.
195 ///
196 /// [`send`]: UnixDatagram::send
197 /// [`recv`]: UnixDatagram::recv
198 /// [`recv_from`]: UnixDatagram::recv_from
199 ///
200 /// # Examples
201 ///
202 #[cfg_attr(target_family = "unix", doc = "```no_run")]
203 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
204 /// use std::os::unix::net::UnixDatagram;
205 ///
206 /// fn main() -> std::io::Result<()> {
207 /// let sock = UnixDatagram::unbound()?;
208 /// match sock.connect("/path/to/the/socket") {
209 /// Ok(sock) => sock,
210 /// Err(e) => {
211 /// println!("Couldn't connect: {e:?}");
212 /// return Err(e)
213 /// }
214 /// };
215 /// Ok(())
216 /// }
217 /// ```
218 #[stable(feature = "unix_socket", since = "1.10.0")]
219 pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
220 unsafe {
221 let (addr, len) = sockaddr_un(path.as_ref())?;
222
223 cvt(libc::connect(self.as_raw_fd(), (&raw const addr) as *const _, len))?;
224 }
225 Ok(())
226 }
227
228 /// Connects the socket to an address.
229 ///
230 /// # Examples
231 ///
232 #[cfg_attr(target_family = "unix", doc = "```no_run")]
233 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
234 /// use std::os::unix::net::{UnixDatagram};
235 ///
236 /// fn main() -> std::io::Result<()> {
237 /// let bound = UnixDatagram::bind("/path/to/socket")?;
238 /// let addr = bound.local_addr()?;
239 ///
240 /// let sock = UnixDatagram::unbound()?;
241 /// match sock.connect_addr(&addr) {
242 /// Ok(sock) => sock,
243 /// Err(e) => {
244 /// println!("Couldn't connect: {e:?}");
245 /// return Err(e)
246 /// }
247 /// };
248 /// Ok(())
249 /// }
250 /// ```
251 #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
252 pub fn connect_addr(&self, socket_addr: &SocketAddr) -> io::Result<()> {
253 unsafe {
254 cvt(libc::connect(
255 self.as_raw_fd(),
256 (&raw const socket_addr.addr) as *const _,
257 socket_addr.len,
258 ))?;
259 }
260 Ok(())
261 }
262
263 /// Creates a new independently owned handle to the underlying socket.
264 ///
265 /// The returned `UnixDatagram` is a reference to the same socket that this
266 /// object references. Both handles can be used to accept incoming
267 /// connections and options set on one side will affect the other.
268 ///
269 /// # Examples
270 ///
271 #[cfg_attr(target_family = "unix", doc = "```no_run")]
272 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
273 /// use std::os::unix::net::UnixDatagram;
274 ///
275 /// fn main() -> std::io::Result<()> {
276 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
277 /// let sock_copy = sock.try_clone().expect("`UnixDatagram::try_clone` should not fail");
278 /// Ok(())
279 /// }
280 /// ```
281 #[stable(feature = "unix_socket", since = "1.10.0")]
282 pub fn try_clone(&self) -> io::Result<UnixDatagram> {
283 self.0.duplicate().map(UnixDatagram)
284 }
285
286 /// Returns the address of this socket.
287 ///
288 /// # Examples
289 ///
290 #[cfg_attr(target_family = "unix", doc = "```no_run")]
291 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
292 /// use std::os::unix::net::UnixDatagram;
293 ///
294 /// fn main() -> std::io::Result<()> {
295 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
296 /// let addr = sock.local_addr().expect("`UnixDatagram::local_addr` should not fail");
297 /// Ok(())
298 /// }
299 /// ```
300 #[stable(feature = "unix_socket", since = "1.10.0")]
301 pub fn local_addr(&self) -> io::Result<SocketAddr> {
302 SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.as_raw_fd(), addr, len) })
303 }
304
305 /// Returns the address of this socket's peer.
306 ///
307 /// The [`connect`] method will connect the socket to a peer.
308 ///
309 /// [`connect`]: UnixDatagram::connect
310 ///
311 /// # Examples
312 ///
313 #[cfg_attr(target_family = "unix", doc = "```no_run")]
314 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
315 /// use std::os::unix::net::UnixDatagram;
316 ///
317 /// fn main() -> std::io::Result<()> {
318 /// let sock = UnixDatagram::unbound()?;
319 /// sock.connect("/path/to/the/socket")?;
320 ///
321 /// let addr = sock.peer_addr().expect("`UnixDatagram::peer_addr` should not fail");
322 /// Ok(())
323 /// }
324 /// ```
325 #[stable(feature = "unix_socket", since = "1.10.0")]
326 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
327 SocketAddr::new(|addr, len| unsafe { libc::getpeername(self.as_raw_fd(), addr, len) })
328 }
329
330 fn recv_from_flags(
331 &self,
332 buf: &mut [u8],
333 flags: core::ffi::c_int,
334 ) -> io::Result<(usize, SocketAddr)> {
335 let mut count = 0;
336 let addr = SocketAddr::new(|addr, len| unsafe {
337 count = libc::recvfrom(
338 self.as_raw_fd(),
339 buf.as_mut_ptr() as *mut _,
340 buf.len(),
341 flags,
342 addr,
343 len,
344 );
345 if count > 0 {
346 1
347 } else if count == 0 {
348 0
349 } else {
350 -1
351 }
352 })?;
353
354 Ok((count as usize, addr))
355 }
356
357 /// Receives data from the socket.
358 ///
359 /// On success, returns the number of bytes read and the address from
360 /// whence the data came.
361 ///
362 /// # Examples
363 ///
364 #[cfg_attr(target_family = "unix", doc = "```no_run")]
365 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
366 /// use std::os::unix::net::UnixDatagram;
367 ///
368 /// fn main() -> std::io::Result<()> {
369 /// let sock = UnixDatagram::unbound()?;
370 /// let mut buf = vec![0; 10];
371 /// let (size, sender) = sock.recv_from(buf.as_mut_slice())?;
372 /// println!("received {size} bytes from {sender:?}");
373 /// Ok(())
374 /// }
375 /// ```
376 #[stable(feature = "unix_socket", since = "1.10.0")]
377 pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
378 self.recv_from_flags(buf, 0)
379 }
380
381 /// Receives data from the socket.
382 ///
383 /// On success, returns the number of bytes read.
384 ///
385 /// # Examples
386 ///
387 #[cfg_attr(target_family = "unix", doc = "```no_run")]
388 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
389 /// use std::os::unix::net::UnixDatagram;
390 ///
391 /// fn main() -> std::io::Result<()> {
392 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
393 /// let mut buf = vec![0; 10];
394 /// sock.recv(buf.as_mut_slice()).expect("`UnixDatagram::recv` should not fail");
395 /// Ok(())
396 /// }
397 /// ```
398 #[stable(feature = "unix_socket", since = "1.10.0")]
399 pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
400 self.0.read(buf)
401 }
402
403 /// Receives data and ancillary data from socket.
404 ///
405 /// On success, returns the number of bytes read, if the data was truncated and the address from whence the msg came.
406 ///
407 /// # Examples
408 ///
409 #[cfg_attr(
410 any(target_os = "android", target_os = "linux", target_os = "cygwin"),
411 doc = "```no_run"
412 )]
413 #[cfg_attr(
414 not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
415 doc = "```ignore"
416 )]
417 /// #![feature(unix_socket_ancillary_data)]
418 /// use std::os::unix::net::{UnixDatagram, SocketAncillary, AncillaryData};
419 /// use std::io::IoSliceMut;
420 ///
421 /// fn main() -> std::io::Result<()> {
422 /// let sock = UnixDatagram::unbound()?;
423 /// let mut buf1 = [1; 8];
424 /// let mut buf2 = [2; 16];
425 /// let mut buf3 = [3; 8];
426 /// let mut bufs = &mut [
427 /// IoSliceMut::new(&mut buf1),
428 /// IoSliceMut::new(&mut buf2),
429 /// IoSliceMut::new(&mut buf3),
430 /// ][..];
431 /// let mut fds = [0; 8];
432 /// let mut ancillary_buffer = [0; 128];
433 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
434 /// let (size, _truncated, sender) = sock.recv_vectored_with_ancillary_from(bufs, &mut ancillary)?;
435 /// println!("received {size}");
436 /// for ancillary_result in ancillary.messages() {
437 /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
438 /// for fd in scm_rights {
439 /// println!("receive file descriptor: {fd}");
440 /// }
441 /// }
442 /// }
443 /// Ok(())
444 /// }
445 /// ```
446 #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
447 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
448 pub fn recv_vectored_with_ancillary_from(
449 &self,
450 bufs: &mut [IoSliceMut<'_>],
451 ancillary: &mut SocketAncillary<'_>,
452 ) -> io::Result<(usize, bool, SocketAddr)> {
453 let (count, truncated, addr) = recv_vectored_with_ancillary_from(&self.0, bufs, ancillary)?;
454 let addr = addr?;
455
456 Ok((count, truncated, addr))
457 }
458
459 /// Receives data and ancillary data from socket.
460 ///
461 /// On success, returns the number of bytes read and if the data was truncated.
462 ///
463 /// # Examples
464 ///
465 #[cfg_attr(
466 any(target_os = "android", target_os = "linux", target_os = "cygwin"),
467 doc = "```no_run"
468 )]
469 #[cfg_attr(
470 not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
471 doc = "```ignore"
472 )]
473 /// #![feature(unix_socket_ancillary_data)]
474 /// use std::os::unix::net::{UnixDatagram, SocketAncillary, AncillaryData};
475 /// use std::io::IoSliceMut;
476 ///
477 /// fn main() -> std::io::Result<()> {
478 /// let sock = UnixDatagram::unbound()?;
479 /// let mut buf1 = [1; 8];
480 /// let mut buf2 = [2; 16];
481 /// let mut buf3 = [3; 8];
482 /// let mut bufs = &mut [
483 /// IoSliceMut::new(&mut buf1),
484 /// IoSliceMut::new(&mut buf2),
485 /// IoSliceMut::new(&mut buf3),
486 /// ][..];
487 /// let mut fds = [0; 8];
488 /// let mut ancillary_buffer = [0; 128];
489 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
490 /// let (size, _truncated) = sock.recv_vectored_with_ancillary(bufs, &mut ancillary)?;
491 /// println!("received {size}");
492 /// for ancillary_result in ancillary.messages() {
493 /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
494 /// for fd in scm_rights {
495 /// println!("receive file descriptor: {fd}");
496 /// }
497 /// }
498 /// }
499 /// Ok(())
500 /// }
501 /// ```
502 #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
503 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
504 pub fn recv_vectored_with_ancillary(
505 &self,
506 bufs: &mut [IoSliceMut<'_>],
507 ancillary: &mut SocketAncillary<'_>,
508 ) -> io::Result<(usize, bool)> {
509 let (count, truncated, addr) = recv_vectored_with_ancillary_from(&self.0, bufs, ancillary)?;
510 addr?;
511
512 Ok((count, truncated))
513 }
514
515 /// Sends data on the socket to the specified address.
516 ///
517 /// On success, returns the number of bytes written.
518 ///
519 /// # Examples
520 ///
521 #[cfg_attr(target_family = "unix", doc = "```no_run")]
522 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
523 /// use std::os::unix::net::UnixDatagram;
524 ///
525 /// fn main() -> std::io::Result<()> {
526 /// let sock = UnixDatagram::unbound()?;
527 /// sock.send_to(b"omelette au fromage", "/some/sock").expect("`UnixDatagram::send_to` should not fail");
528 /// Ok(())
529 /// }
530 /// ```
531 #[stable(feature = "unix_socket", since = "1.10.0")]
532 pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
533 unsafe {
534 let (addr, len) = sockaddr_un(path.as_ref())?;
535
536 let count = cvt(libc::sendto(
537 self.as_raw_fd(),
538 buf.as_ptr() as *const _,
539 buf.len(),
540 MSG_NOSIGNAL,
541 (&raw const addr) as *const _,
542 len,
543 ))?;
544 Ok(count as usize)
545 }
546 }
547
548 /// Sends data on the socket to the specified [SocketAddr].
549 ///
550 /// On success, returns the number of bytes written.
551 ///
552 /// [SocketAddr]: crate::os::unix::net::SocketAddr
553 ///
554 /// # Examples
555 ///
556 #[cfg_attr(target_family = "unix", doc = "```no_run")]
557 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
558 /// use std::os::unix::net::{UnixDatagram};
559 ///
560 /// fn main() -> std::io::Result<()> {
561 /// let bound = UnixDatagram::bind("/path/to/socket")?;
562 /// let addr = bound.local_addr()?;
563 ///
564 /// let sock = UnixDatagram::unbound()?;
565 /// sock.send_to_addr(b"bacon egg and cheese", &addr).expect("`UnixDatagram::send_to_addr` should not fail");
566 /// Ok(())
567 /// }
568 /// ```
569 #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
570 pub fn send_to_addr(&self, buf: &[u8], socket_addr: &SocketAddr) -> io::Result<usize> {
571 unsafe {
572 let count = cvt(libc::sendto(
573 self.as_raw_fd(),
574 buf.as_ptr() as *const _,
575 buf.len(),
576 MSG_NOSIGNAL,
577 (&raw const socket_addr.addr) as *const _,
578 socket_addr.len,
579 ))?;
580 Ok(count as usize)
581 }
582 }
583
584 /// Sends data on the socket to the socket's peer.
585 ///
586 /// The peer address may be set by the `connect` method, and this method
587 /// will return an error if the socket has not already been connected.
588 ///
589 /// On success, returns the number of bytes written.
590 ///
591 /// # Examples
592 ///
593 #[cfg_attr(target_family = "unix", doc = "```no_run")]
594 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
595 /// use std::os::unix::net::UnixDatagram;
596 ///
597 /// fn main() -> std::io::Result<()> {
598 /// let sock = UnixDatagram::unbound()?;
599 /// sock.connect("/some/sock").expect("`UnixDatagram::connect` should not fail");
600 /// sock.send(b"omelette au fromage").expect("`UnixDatagram` is not connected");
601 /// Ok(())
602 /// }
603 /// ```
604 #[stable(feature = "unix_socket", since = "1.10.0")]
605 pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
606 self.0.write(buf)
607 }
608
609 /// Sends data and ancillary data on the socket to the specified address.
610 ///
611 /// On success, returns the number of bytes written.
612 ///
613 /// # Examples
614 ///
615 #[cfg_attr(
616 any(target_os = "android", target_os = "linux", target_os = "cygwin"),
617 doc = "```no_run"
618 )]
619 #[cfg_attr(
620 not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
621 doc = "```ignore"
622 )]
623 /// #![feature(unix_socket_ancillary_data)]
624 /// use std::os::unix::net::{UnixDatagram, SocketAncillary};
625 /// use std::io::IoSlice;
626 ///
627 /// fn main() -> std::io::Result<()> {
628 /// let sock = UnixDatagram::unbound()?;
629 /// let buf1 = [1; 8];
630 /// let buf2 = [2; 16];
631 /// let buf3 = [3; 8];
632 /// let bufs = &[
633 /// IoSlice::new(&buf1),
634 /// IoSlice::new(&buf2),
635 /// IoSlice::new(&buf3),
636 /// ][..];
637 /// let fds = [0, 1, 2];
638 /// let mut ancillary_buffer = [0; 128];
639 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
640 /// ancillary.add_fds(&fds[..]);
641 /// sock.send_vectored_with_ancillary_to(bufs, &mut ancillary, "/some/sock")
642 /// .expect("`UnixDatagram::send_vectored_with_ancillary_to` should not fail");
643 /// Ok(())
644 /// }
645 /// ```
646 #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
647 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
648 pub fn send_vectored_with_ancillary_to<P: AsRef<Path>>(
649 &self,
650 bufs: &[IoSlice<'_>],
651 ancillary: &mut SocketAncillary<'_>,
652 path: P,
653 ) -> io::Result<usize> {
654 send_vectored_with_ancillary_to(&self.0, Some(path.as_ref()), bufs, ancillary)
655 }
656
657 /// Sends data and ancillary data on the socket.
658 ///
659 /// On success, returns the number of bytes written.
660 ///
661 /// # Examples
662 ///
663 #[cfg_attr(
664 any(target_os = "android", target_os = "linux", target_os = "cygwin"),
665 doc = "```no_run"
666 )]
667 #[cfg_attr(
668 not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
669 doc = "```ignore"
670 )]
671 /// #![feature(unix_socket_ancillary_data)]
672 /// use std::os::unix::net::{UnixDatagram, SocketAncillary};
673 /// use std::io::IoSlice;
674 ///
675 /// fn main() -> std::io::Result<()> {
676 /// let sock = UnixDatagram::unbound()?;
677 /// let buf1 = [1; 8];
678 /// let buf2 = [2; 16];
679 /// let buf3 = [3; 8];
680 /// let bufs = &[
681 /// IoSlice::new(&buf1),
682 /// IoSlice::new(&buf2),
683 /// IoSlice::new(&buf3),
684 /// ][..];
685 /// let fds = [0, 1, 2];
686 /// let mut ancillary_buffer = [0; 128];
687 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
688 /// ancillary.add_fds(&fds[..]);
689 /// sock.send_vectored_with_ancillary(bufs, &mut ancillary)
690 /// .expect("`UnixDatagram::send_vectored_with_ancillary` should not fail");
691 /// Ok(())
692 /// }
693 /// ```
694 #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
695 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
696 pub fn send_vectored_with_ancillary(
697 &self,
698 bufs: &[IoSlice<'_>],
699 ancillary: &mut SocketAncillary<'_>,
700 ) -> io::Result<usize> {
701 send_vectored_with_ancillary_to(&self.0, None, bufs, ancillary)
702 }
703
704 /// Sets the read timeout for the socket.
705 ///
706 /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will
707 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`]
708 /// is passed to this method.
709 ///
710 /// [`recv`]: UnixDatagram::recv
711 /// [`recv_from`]: UnixDatagram::recv_from
712 ///
713 /// # Examples
714 ///
715 #[cfg_attr(target_family = "unix", doc = "```")]
716 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
717 /// use std::os::unix::net::UnixDatagram;
718 /// use std::time::Duration;
719 ///
720 /// fn main() -> std::io::Result<()> {
721 /// let sock = UnixDatagram::unbound()?;
722 /// sock.set_read_timeout(Some(Duration::new(1, 0)))
723 /// .expect("`UnixDatagram::set_read_timeout` should not fail");
724 /// Ok(())
725 /// }
726 /// ```
727 ///
728 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
729 /// method:
730 ///
731 #[cfg_attr(target_family = "unix", doc = "```no_run")]
732 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
733 /// use std::io;
734 /// use std::os::unix::net::UnixDatagram;
735 /// use std::time::Duration;
736 ///
737 /// fn main() -> std::io::Result<()> {
738 /// let socket = UnixDatagram::unbound()?;
739 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
740 /// let err = result.unwrap_err();
741 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
742 /// Ok(())
743 /// }
744 /// ```
745 #[stable(feature = "unix_socket", since = "1.10.0")]
746 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
747 self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
748 }
749
750 /// Sets the write timeout for the socket.
751 ///
752 /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will
753 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
754 /// method.
755 ///
756 /// [`send`]: UnixDatagram::send
757 /// [`send_to`]: UnixDatagram::send_to
758 ///
759 /// # Examples
760 ///
761 #[cfg_attr(target_family = "unix", doc = "```")]
762 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
763 /// use std::os::unix::net::UnixDatagram;
764 /// use std::time::Duration;
765 ///
766 /// fn main() -> std::io::Result<()> {
767 /// let sock = UnixDatagram::unbound()?;
768 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
769 /// .expect("`UnixDatagram::set_write_timeout` should not fail");
770 /// Ok(())
771 /// }
772 /// ```
773 ///
774 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
775 /// method:
776 ///
777 #[cfg_attr(target_family = "unix", doc = "```no_run")]
778 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
779 /// use std::io;
780 /// use std::os::unix::net::UnixDatagram;
781 /// use std::time::Duration;
782 ///
783 /// fn main() -> std::io::Result<()> {
784 /// let socket = UnixDatagram::unbound()?;
785 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
786 /// let err = result.unwrap_err();
787 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
788 /// Ok(())
789 /// }
790 /// ```
791 #[stable(feature = "unix_socket", since = "1.10.0")]
792 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
793 self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
794 }
795
796 /// Returns the read timeout of this socket.
797 ///
798 /// # Examples
799 ///
800 #[cfg_attr(target_family = "unix", doc = "```")]
801 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
802 /// use std::os::unix::net::UnixDatagram;
803 /// use std::time::Duration;
804 ///
805 /// fn main() -> std::io::Result<()> {
806 /// let sock = UnixDatagram::unbound()?;
807 /// sock.set_read_timeout(Some(Duration::new(1, 0)))
808 /// .expect("`UnixDatagram::set_read_timeout` should not fail");
809 /// assert_eq!(sock.read_timeout()?, Some(Duration::new(1, 0)));
810 /// Ok(())
811 /// }
812 /// ```
813 #[stable(feature = "unix_socket", since = "1.10.0")]
814 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
815 self.0.timeout(libc::SO_RCVTIMEO)
816 }
817
818 /// Returns the write timeout of this socket.
819 ///
820 /// # Examples
821 ///
822 #[cfg_attr(target_family = "unix", doc = "```")]
823 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
824 /// use std::os::unix::net::UnixDatagram;
825 /// use std::time::Duration;
826 ///
827 /// fn main() -> std::io::Result<()> {
828 /// let sock = UnixDatagram::unbound()?;
829 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
830 /// .expect("`UnixDatagram::set_write_timeout` should not fail");
831 /// assert_eq!(sock.write_timeout()?, Some(Duration::new(1, 0)));
832 /// Ok(())
833 /// }
834 /// ```
835 #[stable(feature = "unix_socket", since = "1.10.0")]
836 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
837 self.0.timeout(libc::SO_SNDTIMEO)
838 }
839
840 /// Moves the socket into or out of nonblocking mode.
841 ///
842 /// # Examples
843 ///
844 #[cfg_attr(target_family = "unix", doc = "```")]
845 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
846 /// use std::os::unix::net::UnixDatagram;
847 ///
848 /// fn main() -> std::io::Result<()> {
849 /// let sock = UnixDatagram::unbound()?;
850 /// sock.set_nonblocking(true).expect("`UnixDatagram::set_nonblocking` should not fail");
851 /// Ok(())
852 /// }
853 /// ```
854 #[stable(feature = "unix_socket", since = "1.10.0")]
855 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
856 self.0.set_nonblocking(nonblocking)
857 }
858
859 /// Set the id of the socket for network filtering purpose
860 ///
861 #[cfg_attr(
862 any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"),
863 doc = "```no_run"
864 )]
865 #[cfg_attr(
866 not(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd")),
867 doc = "```ignore"
868 )]
869 /// #![feature(unix_set_mark)]
870 /// use std::os::unix::net::UnixDatagram;
871 ///
872 /// fn main() -> std::io::Result<()> {
873 /// let sock = UnixDatagram::unbound()?;
874 /// sock.set_mark(32)?;
875 /// Ok(())
876 /// }
877 /// ```
878 #[cfg(any(doc, target_os = "linux", target_os = "freebsd", target_os = "openbsd",))]
879 #[unstable(feature = "unix_set_mark", issue = "96467")]
880 pub fn set_mark(&self, mark: u32) -> io::Result<()> {
881 self.0.set_mark(mark)
882 }
883
884 /// Returns the value of the `SO_ERROR` option.
885 ///
886 /// # Examples
887 ///
888 #[cfg_attr(target_family = "unix", doc = "```no_run")]
889 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
890 /// use std::os::unix::net::UnixDatagram;
891 ///
892 /// fn main() -> std::io::Result<()> {
893 /// let sock = UnixDatagram::unbound()?;
894 /// if let Ok(Some(err)) = sock.take_error() {
895 /// println!("Got error: {err:?}");
896 /// }
897 /// Ok(())
898 /// }
899 /// ```
900 #[stable(feature = "unix_socket", since = "1.10.0")]
901 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
902 self.0.take_error()
903 }
904
905 /// Shut down the read, write, or both halves of this connection.
906 ///
907 /// This function will cause all pending and future I/O calls on the
908 /// specified portions to immediately return with an appropriate value
909 /// (see the documentation of [`Shutdown`]).
910 ///
911 #[cfg_attr(target_family = "unix", doc = "```no_run")]
912 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
913 /// use std::os::unix::net::UnixDatagram;
914 /// use std::net::Shutdown;
915 ///
916 /// fn main() -> std::io::Result<()> {
917 /// let sock = UnixDatagram::unbound()?;
918 /// sock.shutdown(Shutdown::Both).expect("`UnixDatagram::shutdown` should not fail");
919 /// Ok(())
920 /// }
921 /// ```
922 #[stable(feature = "unix_socket", since = "1.10.0")]
923 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
924 self.0.shutdown(how)
925 }
926
927 /// Receives data on the socket from the remote address to which it is
928 /// connected, without removing that data from the queue. On success,
929 /// returns the number of bytes peeked.
930 ///
931 /// Successive calls return the same data. This is accomplished by passing
932 /// `MSG_PEEK` as a flag to the underlying `recv` system call.
933 ///
934 /// # Examples
935 ///
936 #[cfg_attr(target_family = "unix", doc = "```no_run")]
937 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
938 /// #![feature(unix_socket_peek)]
939 ///
940 /// use std::os::unix::net::UnixDatagram;
941 ///
942 /// fn main() -> std::io::Result<()> {
943 /// let socket = UnixDatagram::bind("/tmp/sock")?;
944 /// let mut buf = [0; 10];
945 /// let len = socket.peek(&mut buf).expect("`UnixDatagram::peek` should not fail");
946 /// Ok(())
947 /// }
948 /// ```
949 #[unstable(feature = "unix_socket_peek", issue = "76923")]
950 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
951 self.0.peek(buf)
952 }
953
954 /// Receives a single datagram message on the socket, without removing it from the
955 /// queue. On success, returns the number of bytes read and the origin.
956 ///
957 /// The function must be called with valid byte array `buf` of sufficient size to
958 /// hold the message bytes. If a message is too long to fit in the supplied buffer,
959 /// excess bytes may be discarded.
960 ///
961 /// Successive calls return the same data. This is accomplished by passing
962 /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call.
963 ///
964 /// Do not use this function to implement busy waiting, instead use `libc::poll` to
965 /// synchronize IO events on one or more sockets.
966 ///
967 /// # Examples
968 ///
969 #[cfg_attr(target_family = "unix", doc = "```no_run")]
970 #[cfg_attr(not(target_family = "unix"), doc = "```ignore (needs unix)")]
971 /// #![feature(unix_socket_peek)]
972 ///
973 /// use std::os::unix::net::UnixDatagram;
974 ///
975 /// fn main() -> std::io::Result<()> {
976 /// let socket = UnixDatagram::bind("/tmp/sock")?;
977 /// let mut buf = [0; 10];
978 /// let (len, addr) = socket.peek_from(&mut buf).expect("peek failed");
979 /// Ok(())
980 /// }
981 /// ```
982 #[unstable(feature = "unix_socket_peek", issue = "76923")]
983 pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
984 self.recv_from_flags(buf, libc::MSG_PEEK)
985 }
986}
987
988#[stable(feature = "unix_socket", since = "1.10.0")]
989impl AsRawFd for UnixDatagram {
990 #[inline]
991 fn as_raw_fd(&self) -> RawFd {
992 self.0.as_inner().as_raw_fd()
993 }
994}
995
996#[stable(feature = "unix_socket", since = "1.10.0")]
997impl FromRawFd for UnixDatagram {
998 #[inline]
999 unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
1000 UnixDatagram(Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd))))
1001 }
1002}
1003
1004#[stable(feature = "unix_socket", since = "1.10.0")]
1005impl IntoRawFd for UnixDatagram {
1006 #[inline]
1007 fn into_raw_fd(self) -> RawFd {
1008 self.0.into_inner().into_inner().into_raw_fd()
1009 }
1010}
1011
1012#[stable(feature = "io_safety", since = "1.63.0")]
1013impl AsFd for UnixDatagram {
1014 #[inline]
1015 fn as_fd(&self) -> BorrowedFd<'_> {
1016 self.0.as_inner().as_fd()
1017 }
1018}
1019
1020// SAFETY: It's a tower of 1-field wrappers around OwnedFd.
1021// No methods to close the socket, no methods with safety preconditions,
1022// other than the fd being valid.
1023unsafe_impl_fd_asrefs!(UnixDatagram);
1024
1025#[stable(feature = "io_safety", since = "1.63.0")]
1026impl From<UnixDatagram> for OwnedFd {
1027 /// Takes ownership of a [`UnixDatagram`]'s socket file descriptor.
1028 #[inline]
1029 fn from(unix_datagram: UnixDatagram) -> OwnedFd {
1030 unsafe { OwnedFd::from_raw_fd(unix_datagram.into_raw_fd()) }
1031 }
1032}
1033
1034#[stable(feature = "io_safety", since = "1.63.0")]
1035impl From<OwnedFd> for UnixDatagram {
1036 #[inline]
1037 fn from(owned: OwnedFd) -> Self {
1038 unsafe { Self::from_raw_fd(owned.into_raw_fd()) }
1039 }
1040}
1041
1042impl AsInner<Socket> for UnixDatagram {
1043 #[inline]
1044 fn as_inner(&self) -> &Socket {
1045 &self.0
1046 }
1047}