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