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