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