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