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