[go: up one dir, main page]

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    /// ```
784    /// use std::os::unix::net::UnixDatagram;
785    /// use std::time::Duration;
786    ///
787    /// fn main() -> std::io::Result<()> {
788    ///     let sock = UnixDatagram::unbound()?;
789    ///     sock.set_read_timeout(Some(Duration::new(1, 0)))
790    ///         .expect("set_read_timeout function failed");
791    ///     assert_eq!(sock.read_timeout()?, Some(Duration::new(1, 0)));
792    ///     Ok(())
793    /// }
794    /// ```
795    #[stable(feature = "unix_socket", since = "1.10.0")]
796    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
797        self.0.timeout(libc::SO_RCVTIMEO)
798    }
799
800    /// Returns the write timeout of this socket.
801    ///
802    /// # Examples
803    ///
804    /// ```
805    /// use std::os::unix::net::UnixDatagram;
806    /// use std::time::Duration;
807    ///
808    /// fn main() -> std::io::Result<()> {
809    ///     let sock = UnixDatagram::unbound()?;
810    ///     sock.set_write_timeout(Some(Duration::new(1, 0)))
811    ///         .expect("set_write_timeout function failed");
812    ///     assert_eq!(sock.write_timeout()?, Some(Duration::new(1, 0)));
813    ///     Ok(())
814    /// }
815    /// ```
816    #[stable(feature = "unix_socket", since = "1.10.0")]
817    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
818        self.0.timeout(libc::SO_SNDTIMEO)
819    }
820
821    /// Moves the socket into or out of nonblocking mode.
822    ///
823    /// # Examples
824    ///
825    /// ```
826    /// use std::os::unix::net::UnixDatagram;
827    ///
828    /// fn main() -> std::io::Result<()> {
829    ///     let sock = UnixDatagram::unbound()?;
830    ///     sock.set_nonblocking(true).expect("set_nonblocking function failed");
831    ///     Ok(())
832    /// }
833    /// ```
834    #[stable(feature = "unix_socket", since = "1.10.0")]
835    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
836        self.0.set_nonblocking(nonblocking)
837    }
838
839    /// Set the id of the socket for network filtering purpose
840    ///
841    #[cfg_attr(
842        any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"),
843        doc = "```no_run"
844    )]
845    #[cfg_attr(
846        not(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd")),
847        doc = "```ignore"
848    )]
849    /// #![feature(unix_set_mark)]
850    /// use std::os::unix::net::UnixDatagram;
851    ///
852    /// fn main() -> std::io::Result<()> {
853    ///     let sock = UnixDatagram::unbound()?;
854    ///     sock.set_mark(32)?;
855    ///     Ok(())
856    /// }
857    /// ```
858    #[cfg(any(doc, target_os = "linux", target_os = "freebsd", target_os = "openbsd",))]
859    #[unstable(feature = "unix_set_mark", issue = "96467")]
860    pub fn set_mark(&self, mark: u32) -> io::Result<()> {
861        self.0.set_mark(mark)
862    }
863
864    /// Returns the value of the `SO_ERROR` option.
865    ///
866    /// # Examples
867    ///
868    /// ```no_run
869    /// use std::os::unix::net::UnixDatagram;
870    ///
871    /// fn main() -> std::io::Result<()> {
872    ///     let sock = UnixDatagram::unbound()?;
873    ///     if let Ok(Some(err)) = sock.take_error() {
874    ///         println!("Got error: {err:?}");
875    ///     }
876    ///     Ok(())
877    /// }
878    /// ```
879    #[stable(feature = "unix_socket", since = "1.10.0")]
880    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
881        self.0.take_error()
882    }
883
884    /// Shut down the read, write, or both halves of this connection.
885    ///
886    /// This function will cause all pending and future I/O calls on the
887    /// specified portions to immediately return with an appropriate value
888    /// (see the documentation of [`Shutdown`]).
889    ///
890    /// ```no_run
891    /// use std::os::unix::net::UnixDatagram;
892    /// use std::net::Shutdown;
893    ///
894    /// fn main() -> std::io::Result<()> {
895    ///     let sock = UnixDatagram::unbound()?;
896    ///     sock.shutdown(Shutdown::Both).expect("shutdown function failed");
897    ///     Ok(())
898    /// }
899    /// ```
900    #[stable(feature = "unix_socket", since = "1.10.0")]
901    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
902        self.0.shutdown(how)
903    }
904
905    /// Receives data on the socket from the remote address to which it is
906    /// connected, without removing that data from the queue. On success,
907    /// returns the number of bytes peeked.
908    ///
909    /// Successive calls return the same data. This is accomplished by passing
910    /// `MSG_PEEK` as a flag to the underlying `recv` system call.
911    ///
912    /// # Examples
913    ///
914    /// ```no_run
915    /// #![feature(unix_socket_peek)]
916    ///
917    /// use std::os::unix::net::UnixDatagram;
918    ///
919    /// fn main() -> std::io::Result<()> {
920    ///     let socket = UnixDatagram::bind("/tmp/sock")?;
921    ///     let mut buf = [0; 10];
922    ///     let len = socket.peek(&mut buf).expect("peek failed");
923    ///     Ok(())
924    /// }
925    /// ```
926    #[unstable(feature = "unix_socket_peek", issue = "76923")]
927    pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
928        self.0.peek(buf)
929    }
930
931    /// Receives a single datagram message on the socket, without removing it from the
932    /// queue. On success, returns the number of bytes read and the origin.
933    ///
934    /// The function must be called with valid byte array `buf` of sufficient size to
935    /// hold the message bytes. If a message is too long to fit in the supplied buffer,
936    /// excess bytes may be discarded.
937    ///
938    /// Successive calls return the same data. This is accomplished by passing
939    /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call.
940    ///
941    /// Do not use this function to implement busy waiting, instead use `libc::poll` to
942    /// synchronize IO events on one or more sockets.
943    ///
944    /// # Examples
945    ///
946    /// ```no_run
947    /// #![feature(unix_socket_peek)]
948    ///
949    /// use std::os::unix::net::UnixDatagram;
950    ///
951    /// fn main() -> std::io::Result<()> {
952    ///     let socket = UnixDatagram::bind("/tmp/sock")?;
953    ///     let mut buf = [0; 10];
954    ///     let (len, addr) = socket.peek_from(&mut buf).expect("peek failed");
955    ///     Ok(())
956    /// }
957    /// ```
958    #[unstable(feature = "unix_socket_peek", issue = "76923")]
959    pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
960        self.recv_from_flags(buf, libc::MSG_PEEK)
961    }
962}
963
964#[stable(feature = "unix_socket", since = "1.10.0")]
965impl AsRawFd for UnixDatagram {
966    #[inline]
967    fn as_raw_fd(&self) -> RawFd {
968        self.0.as_inner().as_raw_fd()
969    }
970}
971
972#[stable(feature = "unix_socket", since = "1.10.0")]
973impl FromRawFd for UnixDatagram {
974    #[inline]
975    unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
976        UnixDatagram(Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd))))
977    }
978}
979
980#[stable(feature = "unix_socket", since = "1.10.0")]
981impl IntoRawFd for UnixDatagram {
982    #[inline]
983    fn into_raw_fd(self) -> RawFd {
984        self.0.into_inner().into_inner().into_raw_fd()
985    }
986}
987
988#[stable(feature = "io_safety", since = "1.63.0")]
989impl AsFd for UnixDatagram {
990    #[inline]
991    fn as_fd(&self) -> BorrowedFd<'_> {
992        self.0.as_inner().as_fd()
993    }
994}
995
996#[stable(feature = "io_safety", since = "1.63.0")]
997impl From<UnixDatagram> for OwnedFd {
998    /// Takes ownership of a [`UnixDatagram`]'s socket file descriptor.
999    #[inline]
1000    fn from(unix_datagram: UnixDatagram) -> OwnedFd {
1001        unsafe { OwnedFd::from_raw_fd(unix_datagram.into_raw_fd()) }
1002    }
1003}
1004
1005#[stable(feature = "io_safety", since = "1.63.0")]
1006impl From<OwnedFd> for UnixDatagram {
1007    #[inline]
1008    fn from(owned: OwnedFd) -> Self {
1009        unsafe { Self::from_raw_fd(owned.into_raw_fd()) }
1010    }
1011}
1012
1013impl AsInner<Socket> for UnixDatagram {
1014    #[inline]
1015    fn as_inner(&self) -> &Socket {
1016        &self.0
1017    }
1018}