Skip to main content

std/os/unix/net/
datagram.rs

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