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