|
59 | 59 | #![doc(test(attr(deny(warnings))))]
|
60 | 60 |
|
61 | 61 | use std::fmt;
|
| 62 | +#[cfg(not(target_os = "redox"))] |
| 63 | +use std::io::IoSlice; |
| 64 | +#[cfg(not(target_os = "redox"))] |
| 65 | +use std::marker::PhantomData; |
| 66 | +#[cfg(not(target_os = "redox"))] |
| 67 | +use std::mem; |
62 | 68 | use std::mem::MaybeUninit;
|
63 | 69 | use std::net::SocketAddr;
|
64 | 70 | use std::ops::{Deref, DerefMut};
|
@@ -562,3 +568,97 @@ impl TcpKeepalive {
|
562 | 568 | }
|
563 | 569 | }
|
564 | 570 | }
|
| 571 | + |
| 572 | +/// Configuration of a `{send,recv}msg` system call. |
| 573 | +/// |
| 574 | +/// This wraps `msghdr` on Unix and `WSAMSG` on Windows. |
| 575 | +#[cfg(not(target_os = "redox"))] |
| 576 | +pub struct MsgHdr<'addr, 'bufs, 'control> { |
| 577 | + inner: sys::msghdr, |
| 578 | + #[allow(clippy::type_complexity)] |
| 579 | + _lifetimes: PhantomData<(&'addr SockAddr, &'bufs [&'bufs [u8]], &'control [u8])>, |
| 580 | +} |
| 581 | + |
| 582 | +#[cfg(not(target_os = "redox"))] |
| 583 | +impl<'addr, 'bufs, 'control> MsgHdr<'addr, 'bufs, 'control> { |
| 584 | + /// Create a new `MsgHdr` with all empty/zero fields. |
| 585 | + #[allow(clippy::new_without_default)] |
| 586 | + pub fn new() -> MsgHdr<'addr, 'bufs, 'control> { |
| 587 | + // SAFETY: all zero is valid for `msghdr` and `WSAMSG`. |
| 588 | + MsgHdr { |
| 589 | + inner: unsafe { mem::zeroed() }, |
| 590 | + _lifetimes: PhantomData, |
| 591 | + } |
| 592 | + } |
| 593 | + |
| 594 | + /// Set the address (name) of the message. |
| 595 | + /// |
| 596 | + /// Corresponds to setting `msg_name` and `msg_namelen` on Unix and `name` |
| 597 | + /// and `namelen` on Windows. |
| 598 | + pub fn with_addr(mut self, addr: &'addr SockAddr) -> Self { |
| 599 | + sys::set_msghdr_name(&mut self.inner, addr); |
| 600 | + self |
| 601 | + } |
| 602 | + |
| 603 | + /// Set the mutable address (name) of the message. Same as [`with_addr`], |
| 604 | + /// but with a mutable address. |
| 605 | + /// |
| 606 | + /// [`with_addr`]: MsgHdr::with_addr |
| 607 | + pub fn with_addr_mut(mut self, addr: &'addr mut SockAddr) -> Self { |
| 608 | + sys::set_msghdr_name(&mut self.inner, addr); |
| 609 | + self |
| 610 | + } |
| 611 | + |
| 612 | + /// Set the buffer(s) of the message. |
| 613 | + /// |
| 614 | + /// Corresponds to setting `msg_iov` and `msg_iovlen` on Unix and `lpBuffers` |
| 615 | + /// and `dwBufferCount` on Windows. |
| 616 | + pub fn with_buffers(mut self, bufs: &'bufs [IoSlice<'bufs>]) -> Self { |
| 617 | + let ptr = bufs.as_ptr().cast_mut().cast(); |
| 618 | + sys::set_msghdr_iov(&mut self.inner, ptr, bufs.len()); |
| 619 | + self |
| 620 | + } |
| 621 | + |
| 622 | + /// Set the mutable buffer(s) of the message. Same as [`with_buffers`], but |
| 623 | + /// with mutable buffers. |
| 624 | + /// |
| 625 | + /// [`with_buffers`]: MsgHdr::with_buffers |
| 626 | + pub fn with_buffers_mut(mut self, bufs: &'bufs mut [MaybeUninitSlice<'bufs>]) -> Self { |
| 627 | + sys::set_msghdr_iov(&mut self.inner, bufs.as_mut_ptr().cast(), bufs.len()); |
| 628 | + self |
| 629 | + } |
| 630 | + |
| 631 | + /// Set the control buffer of the message. |
| 632 | + /// |
| 633 | + /// Corresponds to setting `msg_control` and `msg_controllen` on Unix and |
| 634 | + /// `Control` on Windows. |
| 635 | + pub fn with_control(mut self, buf: &'control [u8]) -> Self { |
| 636 | + let ptr = buf.as_ptr().cast_mut().cast(); |
| 637 | + sys::set_msghdr_control(&mut self.inner, ptr, buf.len()); |
| 638 | + self |
| 639 | + } |
| 640 | + |
| 641 | + /// Set the mutable control buffer of the message. Same as [`with_control`], |
| 642 | + /// but with a mutable buffers. |
| 643 | + /// |
| 644 | + /// [`with_control`]: MsgHdr::with_control |
| 645 | + pub fn with_control_mut(mut self, buf: &'control mut [u8]) -> Self { |
| 646 | + sys::set_msghdr_control(&mut self.inner, buf.as_mut_ptr().cast(), buf.len()); |
| 647 | + self |
| 648 | + } |
| 649 | + |
| 650 | + /// Set the flags of the message. |
| 651 | + /// |
| 652 | + /// Corresponds to setting `msg_flags` on Unix and `dwFlags` on Windows. |
| 653 | + pub fn with_flags(mut self, flags: sys::c_int) -> Self { |
| 654 | + sys::set_msghdr_flags(&mut self.inner, flags); |
| 655 | + self |
| 656 | + } |
| 657 | +} |
| 658 | + |
| 659 | +#[cfg(not(target_os = "redox"))] |
| 660 | +impl<'name, 'bufs, 'control> fmt::Debug for MsgHdr<'name, 'bufs, 'control> { |
| 661 | + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 662 | + "MsgHdr".fmt(fmt) |
| 663 | + } |
| 664 | +} |
0 commit comments