]> git.proxmox.com Git - rustc.git/blob - library/std/src/os/unix/net/datagram.rs
New upstream version 1.61.0+dfsg1
[rustc.git] / library / std / src / os / unix / net / datagram.rs
1 #[cfg(any(
2 doc,
3 target_os = "android",
4 target_os = "dragonfly",
5 target_os = "emscripten",
6 target_os = "freebsd",
7 target_os = "linux",
8 target_os = "netbsd",
9 target_os = "openbsd",
10 ))]
11 use super::{recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to, SocketAncillary};
12 use super::{sockaddr_un, SocketAddr};
13 #[cfg(any(
14 target_os = "android",
15 target_os = "dragonfly",
16 target_os = "emscripten",
17 target_os = "freebsd",
18 target_os = "linux",
19 target_os = "netbsd",
20 target_os = "openbsd",
21 ))]
22 use crate::io::{IoSlice, IoSliceMut};
23 use crate::net::Shutdown;
24 use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
25 use crate::path::Path;
26 use crate::sys::cvt;
27 use crate::sys::net::Socket;
28 use crate::sys_common::{AsInner, FromInner, IntoInner};
29 use crate::time::Duration;
30 use crate::{fmt, io};
31
32 #[cfg(any(
33 target_os = "linux",
34 target_os = "android",
35 target_os = "dragonfly",
36 target_os = "freebsd",
37 target_os = "openbsd",
38 target_os = "netbsd",
39 target_os = "haiku"
40 ))]
41 use libc::MSG_NOSIGNAL;
42 #[cfg(not(any(
43 target_os = "linux",
44 target_os = "android",
45 target_os = "dragonfly",
46 target_os = "freebsd",
47 target_os = "openbsd",
48 target_os = "netbsd",
49 target_os = "haiku"
50 )))]
51 const MSG_NOSIGNAL: libc::c_int = 0x0;
52
53 /// A Unix datagram socket.
54 ///
55 /// # Examples
56 ///
57 /// ```no_run
58 /// use std::os::unix::net::UnixDatagram;
59 ///
60 /// fn main() -> std::io::Result<()> {
61 /// let socket = UnixDatagram::bind("/path/to/my/socket")?;
62 /// socket.send_to(b"hello world", "/path/to/other/socket")?;
63 /// let mut buf = [0; 100];
64 /// let (count, address) = socket.recv_from(&mut buf)?;
65 /// println!("socket {:?} sent {:?}", address, &buf[..count]);
66 /// Ok(())
67 /// }
68 /// ```
69 #[stable(feature = "unix_socket", since = "1.10.0")]
70 pub struct UnixDatagram(Socket);
71
72 #[stable(feature = "unix_socket", since = "1.10.0")]
73 impl fmt::Debug for UnixDatagram {
74 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
75 let mut builder = fmt.debug_struct("UnixDatagram");
76 builder.field("fd", self.0.as_inner());
77 if let Ok(addr) = self.local_addr() {
78 builder.field("local", &addr);
79 }
80 if let Ok(addr) = self.peer_addr() {
81 builder.field("peer", &addr);
82 }
83 builder.finish()
84 }
85 }
86
87 impl UnixDatagram {
88 /// Creates a Unix datagram socket bound to the given path.
89 ///
90 /// # Examples
91 ///
92 /// ```no_run
93 /// use std::os::unix::net::UnixDatagram;
94 ///
95 /// let sock = match UnixDatagram::bind("/path/to/the/socket") {
96 /// Ok(sock) => sock,
97 /// Err(e) => {
98 /// println!("Couldn't bind: {e:?}");
99 /// return
100 /// }
101 /// };
102 /// ```
103 #[stable(feature = "unix_socket", since = "1.10.0")]
104 pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
105 unsafe {
106 let socket = UnixDatagram::unbound()?;
107 let (addr, len) = sockaddr_un(path.as_ref())?;
108
109 cvt(libc::bind(socket.as_raw_fd(), &addr as *const _ as *const _, len as _))?;
110
111 Ok(socket)
112 }
113 }
114
115 /// Creates a Unix datagram socket bound to an address.
116 ///
117 /// # Examples
118 ///
119 /// ```no_run
120 /// #![feature(unix_socket_abstract)]
121 /// use std::os::unix::net::{UnixDatagram};
122 ///
123 /// fn main() -> std::io::Result<()> {
124 /// let sock1 = UnixDatagram::bind("path/to/socket")?;
125 /// let addr = sock1.local_addr()?;
126 ///
127 /// let sock2 = match UnixDatagram::bind_addr(&addr) {
128 /// Ok(sock) => sock,
129 /// Err(err) => {
130 /// println!("Couldn't bind: {err:?}");
131 /// return Err(err);
132 /// }
133 /// };
134 /// Ok(())
135 /// }
136 /// ```
137 #[unstable(feature = "unix_socket_abstract", issue = "85410")]
138 pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result<UnixDatagram> {
139 unsafe {
140 let socket = UnixDatagram::unbound()?;
141 cvt(libc::bind(
142 socket.as_raw_fd(),
143 &socket_addr.addr as *const _ as *const _,
144 socket_addr.len as _,
145 ))?;
146 Ok(socket)
147 }
148 }
149
150 /// Creates a Unix Datagram socket which is not bound to any address.
151 ///
152 /// # Examples
153 ///
154 /// ```no_run
155 /// use std::os::unix::net::UnixDatagram;
156 ///
157 /// let sock = match UnixDatagram::unbound() {
158 /// Ok(sock) => sock,
159 /// Err(e) => {
160 /// println!("Couldn't unbound: {e:?}");
161 /// return
162 /// }
163 /// };
164 /// ```
165 #[stable(feature = "unix_socket", since = "1.10.0")]
166 pub fn unbound() -> io::Result<UnixDatagram> {
167 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?;
168 Ok(UnixDatagram(inner))
169 }
170
171 /// Creates an unnamed pair of connected sockets.
172 ///
173 /// Returns two `UnixDatagrams`s which are connected to each other.
174 ///
175 /// # Examples
176 ///
177 /// ```no_run
178 /// use std::os::unix::net::UnixDatagram;
179 ///
180 /// let (sock1, sock2) = match UnixDatagram::pair() {
181 /// Ok((sock1, sock2)) => (sock1, sock2),
182 /// Err(e) => {
183 /// println!("Couldn't unbound: {e:?}");
184 /// return
185 /// }
186 /// };
187 /// ```
188 #[stable(feature = "unix_socket", since = "1.10.0")]
189 pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
190 let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?;
191 Ok((UnixDatagram(i1), UnixDatagram(i2)))
192 }
193
194 /// Connects the socket to the specified path address.
195 ///
196 /// The [`send`] method may be used to send data to the specified address.
197 /// [`recv`] and [`recv_from`] will only receive data from that address.
198 ///
199 /// [`send`]: UnixDatagram::send
200 /// [`recv`]: UnixDatagram::recv
201 /// [`recv_from`]: UnixDatagram::recv_from
202 ///
203 /// # Examples
204 ///
205 /// ```no_run
206 /// use std::os::unix::net::UnixDatagram;
207 ///
208 /// fn main() -> std::io::Result<()> {
209 /// let sock = UnixDatagram::unbound()?;
210 /// match sock.connect("/path/to/the/socket") {
211 /// Ok(sock) => sock,
212 /// Err(e) => {
213 /// println!("Couldn't connect: {e:?}");
214 /// return Err(e)
215 /// }
216 /// };
217 /// Ok(())
218 /// }
219 /// ```
220 #[stable(feature = "unix_socket", since = "1.10.0")]
221 pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
222 unsafe {
223 let (addr, len) = sockaddr_un(path.as_ref())?;
224
225 cvt(libc::connect(self.as_raw_fd(), &addr as *const _ as *const _, len))?;
226 }
227 Ok(())
228 }
229
230 /// Connects the socket to an address.
231 ///
232 /// # Examples
233 ///
234 /// ```no_run
235 /// #![feature(unix_socket_abstract)]
236 /// use std::os::unix::net::{UnixDatagram};
237 ///
238 /// fn main() -> std::io::Result<()> {
239 /// let bound = UnixDatagram::bind("/path/to/socket")?;
240 /// let addr = bound.local_addr()?;
241 ///
242 /// let sock = UnixDatagram::unbound()?;
243 /// match sock.connect_addr(&addr) {
244 /// Ok(sock) => sock,
245 /// Err(e) => {
246 /// println!("Couldn't connect: {e:?}");
247 /// return Err(e)
248 /// }
249 /// };
250 /// Ok(())
251 /// }
252 /// ```
253 #[unstable(feature = "unix_socket_abstract", issue = "85410")]
254 pub fn connect_addr(&self, socket_addr: &SocketAddr) -> io::Result<()> {
255 unsafe {
256 cvt(libc::connect(
257 self.as_raw_fd(),
258 &socket_addr.addr as *const _ as *const _,
259 socket_addr.len,
260 ))?;
261 }
262 Ok(())
263 }
264
265 /// Creates a new independently owned handle to the underlying socket.
266 ///
267 /// The returned `UnixDatagram` is a reference to the same socket that this
268 /// object references. Both handles can be used to accept incoming
269 /// connections and options set on one side will affect the other.
270 ///
271 /// # Examples
272 ///
273 /// ```no_run
274 /// use std::os::unix::net::UnixDatagram;
275 ///
276 /// fn main() -> std::io::Result<()> {
277 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
278 /// let sock_copy = sock.try_clone().expect("try_clone failed");
279 /// Ok(())
280 /// }
281 /// ```
282 #[stable(feature = "unix_socket", since = "1.10.0")]
283 pub fn try_clone(&self) -> io::Result<UnixDatagram> {
284 self.0.duplicate().map(UnixDatagram)
285 }
286
287 /// Returns the address of this socket.
288 ///
289 /// # Examples
290 ///
291 /// ```no_run
292 /// use std::os::unix::net::UnixDatagram;
293 ///
294 /// fn main() -> std::io::Result<()> {
295 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
296 /// let addr = sock.local_addr().expect("Couldn't get local address");
297 /// Ok(())
298 /// }
299 /// ```
300 #[stable(feature = "unix_socket", since = "1.10.0")]
301 pub fn local_addr(&self) -> io::Result<SocketAddr> {
302 SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.as_raw_fd(), addr, len) })
303 }
304
305 /// Returns the address of this socket's peer.
306 ///
307 /// The [`connect`] method will connect the socket to a peer.
308 ///
309 /// [`connect`]: UnixDatagram::connect
310 ///
311 /// # Examples
312 ///
313 /// ```no_run
314 /// use std::os::unix::net::UnixDatagram;
315 ///
316 /// fn main() -> std::io::Result<()> {
317 /// let sock = UnixDatagram::unbound()?;
318 /// sock.connect("/path/to/the/socket")?;
319 ///
320 /// let addr = sock.peer_addr().expect("Couldn't get peer address");
321 /// Ok(())
322 /// }
323 /// ```
324 #[stable(feature = "unix_socket", since = "1.10.0")]
325 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
326 SocketAddr::new(|addr, len| unsafe { libc::getpeername(self.as_raw_fd(), addr, len) })
327 }
328
329 fn recv_from_flags(
330 &self,
331 buf: &mut [u8],
332 flags: libc::c_int,
333 ) -> io::Result<(usize, SocketAddr)> {
334 let mut count = 0;
335 let addr = SocketAddr::new(|addr, len| unsafe {
336 count = libc::recvfrom(
337 self.as_raw_fd(),
338 buf.as_mut_ptr() as *mut _,
339 buf.len(),
340 flags,
341 addr,
342 len,
343 );
344 if count > 0 {
345 1
346 } else if count == 0 {
347 0
348 } else {
349 -1
350 }
351 })?;
352
353 Ok((count as usize, addr))
354 }
355
356 /// Receives data from the socket.
357 ///
358 /// On success, returns the number of bytes read and the address from
359 /// whence the data came.
360 ///
361 /// # Examples
362 ///
363 /// ```no_run
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 /// ```no_run
386 /// use std::os::unix::net::UnixDatagram;
387 ///
388 /// fn main() -> std::io::Result<()> {
389 /// let sock = UnixDatagram::bind("/path/to/the/socket")?;
390 /// let mut buf = vec![0; 10];
391 /// sock.recv(buf.as_mut_slice()).expect("recv function failed");
392 /// Ok(())
393 /// }
394 /// ```
395 #[stable(feature = "unix_socket", since = "1.10.0")]
396 pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
397 self.0.read(buf)
398 }
399
400 /// Receives data and ancillary data from socket.
401 ///
402 /// On success, returns the number of bytes read, if the data was truncated and the address from whence the msg came.
403 ///
404 /// # Examples
405 ///
406 /// ```no_run
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(
437 target_os = "android",
438 target_os = "dragonfly",
439 target_os = "emscripten",
440 target_os = "freebsd",
441 target_os = "linux",
442 target_os = "netbsd",
443 target_os = "openbsd",
444 ))]
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 /// ```no_run
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(
494 target_os = "android",
495 target_os = "dragonfly",
496 target_os = "emscripten",
497 target_os = "freebsd",
498 target_os = "linux",
499 target_os = "netbsd",
500 target_os = "openbsd",
501 ))]
502 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
503 pub fn recv_vectored_with_ancillary(
504 &self,
505 bufs: &mut [IoSliceMut<'_>],
506 ancillary: &mut SocketAncillary<'_>,
507 ) -> io::Result<(usize, bool)> {
508 let (count, truncated, addr) = recv_vectored_with_ancillary_from(&self.0, bufs, ancillary)?;
509 addr?;
510
511 Ok((count, truncated))
512 }
513
514 /// Sends data on the socket to the specified address.
515 ///
516 /// On success, returns the number of bytes written.
517 ///
518 /// # Examples
519 ///
520 /// ```no_run
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("send_to function failed");
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 &addr as *const _ 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 /// ```no_run
555 /// #![feature(unix_socket_abstract)]
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("send_to_addr function failed");
564 /// Ok(())
565 /// }
566 /// ```
567 #[unstable(feature = "unix_socket_abstract", issue = "85410")]
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 &socket_addr.addr as *const _ 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 /// ```no_run
592 /// use std::os::unix::net::UnixDatagram;
593 ///
594 /// fn main() -> std::io::Result<()> {
595 /// let sock = UnixDatagram::unbound()?;
596 /// sock.connect("/some/sock").expect("Couldn't connect");
597 /// sock.send(b"omelette au fromage").expect("send_to function failed");
598 /// Ok(())
599 /// }
600 /// ```
601 #[stable(feature = "unix_socket", since = "1.10.0")]
602 pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
603 self.0.write(buf)
604 }
605
606 /// Sends data and ancillary data on the socket to the specified address.
607 ///
608 /// On success, returns the number of bytes written.
609 ///
610 /// # Examples
611 ///
612 /// ```no_run
613 /// #![feature(unix_socket_ancillary_data)]
614 /// use std::os::unix::net::{UnixDatagram, SocketAncillary};
615 /// use std::io::IoSlice;
616 ///
617 /// fn main() -> std::io::Result<()> {
618 /// let sock = UnixDatagram::unbound()?;
619 /// let buf1 = [1; 8];
620 /// let buf2 = [2; 16];
621 /// let buf3 = [3; 8];
622 /// let bufs = &[
623 /// IoSlice::new(&buf1),
624 /// IoSlice::new(&buf2),
625 /// IoSlice::new(&buf3),
626 /// ][..];
627 /// let fds = [0, 1, 2];
628 /// let mut ancillary_buffer = [0; 128];
629 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
630 /// ancillary.add_fds(&fds[..]);
631 /// sock.send_vectored_with_ancillary_to(bufs, &mut ancillary, "/some/sock")
632 /// .expect("send_vectored_with_ancillary_to function failed");
633 /// Ok(())
634 /// }
635 /// ```
636 #[cfg(any(
637 target_os = "android",
638 target_os = "dragonfly",
639 target_os = "emscripten",
640 target_os = "freebsd",
641 target_os = "linux",
642 target_os = "netbsd",
643 target_os = "openbsd",
644 ))]
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 /// ```no_run
662 /// #![feature(unix_socket_ancillary_data)]
663 /// use std::os::unix::net::{UnixDatagram, SocketAncillary};
664 /// use std::io::IoSlice;
665 ///
666 /// fn main() -> std::io::Result<()> {
667 /// let sock = UnixDatagram::unbound()?;
668 /// let buf1 = [1; 8];
669 /// let buf2 = [2; 16];
670 /// let buf3 = [3; 8];
671 /// let bufs = &[
672 /// IoSlice::new(&buf1),
673 /// IoSlice::new(&buf2),
674 /// IoSlice::new(&buf3),
675 /// ][..];
676 /// let fds = [0, 1, 2];
677 /// let mut ancillary_buffer = [0; 128];
678 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
679 /// ancillary.add_fds(&fds[..]);
680 /// sock.send_vectored_with_ancillary(bufs, &mut ancillary)
681 /// .expect("send_vectored_with_ancillary function failed");
682 /// Ok(())
683 /// }
684 /// ```
685 #[cfg(any(
686 target_os = "android",
687 target_os = "dragonfly",
688 target_os = "emscripten",
689 target_os = "freebsd",
690 target_os = "linux",
691 target_os = "netbsd",
692 target_os = "openbsd",
693 ))]
694 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
695 pub fn send_vectored_with_ancillary(
696 &self,
697 bufs: &[IoSlice<'_>],
698 ancillary: &mut SocketAncillary<'_>,
699 ) -> io::Result<usize> {
700 send_vectored_with_ancillary_to(&self.0, None, bufs, ancillary)
701 }
702
703 /// Sets the read timeout for the socket.
704 ///
705 /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will
706 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`]
707 /// is passed to this method.
708 ///
709 /// [`recv`]: UnixDatagram::recv
710 /// [`recv_from`]: UnixDatagram::recv_from
711 ///
712 /// # Examples
713 ///
714 /// ```
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("set_read_timeout function failed");
722 /// Ok(())
723 /// }
724 /// ```
725 ///
726 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
727 /// method:
728 ///
729 /// ```no_run
730 /// use std::io;
731 /// use std::os::unix::net::UnixDatagram;
732 /// use std::time::Duration;
733 ///
734 /// fn main() -> std::io::Result<()> {
735 /// let socket = UnixDatagram::unbound()?;
736 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
737 /// let err = result.unwrap_err();
738 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
739 /// Ok(())
740 /// }
741 /// ```
742 #[stable(feature = "unix_socket", since = "1.10.0")]
743 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
744 self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
745 }
746
747 /// Sets the write timeout for the socket.
748 ///
749 /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will
750 /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
751 /// method.
752 ///
753 /// [`send`]: UnixDatagram::send
754 /// [`send_to`]: UnixDatagram::send_to
755 ///
756 /// # Examples
757 ///
758 /// ```
759 /// use std::os::unix::net::UnixDatagram;
760 /// use std::time::Duration;
761 ///
762 /// fn main() -> std::io::Result<()> {
763 /// let sock = UnixDatagram::unbound()?;
764 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
765 /// .expect("set_write_timeout function failed");
766 /// Ok(())
767 /// }
768 /// ```
769 ///
770 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
771 /// method:
772 ///
773 /// ```no_run
774 /// use std::io;
775 /// use std::os::unix::net::UnixDatagram;
776 /// use std::time::Duration;
777 ///
778 /// fn main() -> std::io::Result<()> {
779 /// let socket = UnixDatagram::unbound()?;
780 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
781 /// let err = result.unwrap_err();
782 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
783 /// Ok(())
784 /// }
785 /// ```
786 #[stable(feature = "unix_socket", since = "1.10.0")]
787 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
788 self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
789 }
790
791 /// Returns the read timeout of this socket.
792 ///
793 /// # Examples
794 ///
795 /// ```
796 /// use std::os::unix::net::UnixDatagram;
797 /// use std::time::Duration;
798 ///
799 /// fn main() -> std::io::Result<()> {
800 /// let sock = UnixDatagram::unbound()?;
801 /// sock.set_read_timeout(Some(Duration::new(1, 0)))
802 /// .expect("set_read_timeout function failed");
803 /// assert_eq!(sock.read_timeout()?, Some(Duration::new(1, 0)));
804 /// Ok(())
805 /// }
806 /// ```
807 #[stable(feature = "unix_socket", since = "1.10.0")]
808 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
809 self.0.timeout(libc::SO_RCVTIMEO)
810 }
811
812 /// Returns the write timeout of this socket.
813 ///
814 /// # Examples
815 ///
816 /// ```
817 /// use std::os::unix::net::UnixDatagram;
818 /// use std::time::Duration;
819 ///
820 /// fn main() -> std::io::Result<()> {
821 /// let sock = UnixDatagram::unbound()?;
822 /// sock.set_write_timeout(Some(Duration::new(1, 0)))
823 /// .expect("set_write_timeout function failed");
824 /// assert_eq!(sock.write_timeout()?, Some(Duration::new(1, 0)));
825 /// Ok(())
826 /// }
827 /// ```
828 #[stable(feature = "unix_socket", since = "1.10.0")]
829 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
830 self.0.timeout(libc::SO_SNDTIMEO)
831 }
832
833 /// Moves the socket into or out of nonblocking mode.
834 ///
835 /// # Examples
836 ///
837 /// ```
838 /// use std::os::unix::net::UnixDatagram;
839 ///
840 /// fn main() -> std::io::Result<()> {
841 /// let sock = UnixDatagram::unbound()?;
842 /// sock.set_nonblocking(true).expect("set_nonblocking function failed");
843 /// Ok(())
844 /// }
845 /// ```
846 #[stable(feature = "unix_socket", since = "1.10.0")]
847 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
848 self.0.set_nonblocking(nonblocking)
849 }
850
851 /// Moves the socket to pass unix credentials as control message in [`SocketAncillary`].
852 ///
853 /// Set the socket option `SO_PASSCRED`.
854 ///
855 /// # Examples
856 ///
857 #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
858 #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
859 /// #![feature(unix_socket_ancillary_data)]
860 /// use std::os::unix::net::UnixDatagram;
861 ///
862 /// fn main() -> std::io::Result<()> {
863 /// let sock = UnixDatagram::unbound()?;
864 /// sock.set_passcred(true).expect("set_passcred function failed");
865 /// Ok(())
866 /// }
867 /// ```
868 #[cfg(any(doc, target_os = "android", target_os = "linux",))]
869 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
870 pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
871 self.0.set_passcred(passcred)
872 }
873
874 /// Get the current value of the socket for passing unix credentials in [`SocketAncillary`].
875 /// This value can be change by [`set_passcred`].
876 ///
877 /// Get the socket option `SO_PASSCRED`.
878 ///
879 /// [`set_passcred`]: UnixDatagram::set_passcred
880 #[cfg(any(doc, target_os = "android", target_os = "linux",))]
881 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
882 pub fn passcred(&self) -> io::Result<bool> {
883 self.0.passcred()
884 }
885
886 /// Returns the value of the `SO_ERROR` option.
887 ///
888 /// # Examples
889 ///
890 /// ```no_run
891 /// use std::os::unix::net::UnixDatagram;
892 ///
893 /// fn main() -> std::io::Result<()> {
894 /// let sock = UnixDatagram::unbound()?;
895 /// if let Ok(Some(err)) = sock.take_error() {
896 /// println!("Got error: {err:?}");
897 /// }
898 /// Ok(())
899 /// }
900 /// ```
901 #[stable(feature = "unix_socket", since = "1.10.0")]
902 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
903 self.0.take_error()
904 }
905
906 /// Shut down the read, write, or both halves of this connection.
907 ///
908 /// This function will cause all pending and future I/O calls on the
909 /// specified portions to immediately return with an appropriate value
910 /// (see the documentation of [`Shutdown`]).
911 ///
912 /// ```no_run
913 /// use std::os::unix::net::UnixDatagram;
914 /// use std::net::Shutdown;
915 ///
916 /// fn main() -> std::io::Result<()> {
917 /// let sock = UnixDatagram::unbound()?;
918 /// sock.shutdown(Shutdown::Both).expect("shutdown function failed");
919 /// Ok(())
920 /// }
921 /// ```
922 #[stable(feature = "unix_socket", since = "1.10.0")]
923 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
924 self.0.shutdown(how)
925 }
926
927 /// Receives data on the socket from the remote address to which it is
928 /// connected, without removing that data from the queue. On success,
929 /// returns the number of bytes peeked.
930 ///
931 /// Successive calls return the same data. This is accomplished by passing
932 /// `MSG_PEEK` as a flag to the underlying `recv` system call.
933 ///
934 /// # Examples
935 ///
936 /// ```no_run
937 /// #![feature(unix_socket_peek)]
938 ///
939 /// use std::os::unix::net::UnixDatagram;
940 ///
941 /// fn main() -> std::io::Result<()> {
942 /// let socket = UnixDatagram::bind("/tmp/sock")?;
943 /// let mut buf = [0; 10];
944 /// let len = socket.peek(&mut buf).expect("peek failed");
945 /// Ok(())
946 /// }
947 /// ```
948 #[unstable(feature = "unix_socket_peek", issue = "76923")]
949 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
950 self.0.peek(buf)
951 }
952
953 /// Receives a single datagram message on the socket, without removing it from the
954 /// queue. On success, returns the number of bytes read and the origin.
955 ///
956 /// The function must be called with valid byte array `buf` of sufficient size to
957 /// hold the message bytes. If a message is too long to fit in the supplied buffer,
958 /// excess bytes may be discarded.
959 ///
960 /// Successive calls return the same data. This is accomplished by passing
961 /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call.
962 ///
963 /// Do not use this function to implement busy waiting, instead use `libc::poll` to
964 /// synchronize IO events on one or more sockets.
965 ///
966 /// # Examples
967 ///
968 /// ```no_run
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")]
987 impl 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")]
995 impl 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")]
1003 impl 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 #[unstable(feature = "io_safety", issue = "87074")]
1011 impl AsFd for UnixDatagram {
1012 #[inline]
1013 fn as_fd(&self) -> BorrowedFd<'_> {
1014 self.0.as_inner().as_fd()
1015 }
1016 }
1017
1018 #[unstable(feature = "io_safety", issue = "87074")]
1019 impl From<UnixDatagram> for OwnedFd {
1020 #[inline]
1021 fn from(unix_datagram: UnixDatagram) -> OwnedFd {
1022 unsafe { OwnedFd::from_raw_fd(unix_datagram.into_raw_fd()) }
1023 }
1024 }
1025
1026 #[unstable(feature = "io_safety", issue = "87074")]
1027 impl From<OwnedFd> for UnixDatagram {
1028 #[inline]
1029 fn from(owned: OwnedFd) -> Self {
1030 unsafe { Self::from_raw_fd(owned.into_raw_fd()) }
1031 }
1032 }