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