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