diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs index 4e70aab6607c2..7600614f8ef4f 100644 --- a/library/std/src/os/unix/net/ancillary.rs +++ b/library/std/src/os/unix/net/ancillary.rs @@ -1,5 +1,9 @@ +#![allow(dead_code, unused_imports, unused_variables)] + +use crate::collections::TryReserveError; use crate::ffi::c_int; use crate::mem::{size_of, MaybeUninit}; +use crate::os::unix::io::{BorrowedFd, OwnedFd, RawFd}; // Wrapper around `libc::CMSG_LEN` to safely decouple from OS-specific ints. // @@ -93,7 +97,6 @@ impl ControlMessage<'_> { CMSG_SPACE(self.data.len()) } - #[allow(dead_code)] // currently the only use is in the test suite pub(super) fn copy_to_slice<'a>(&self, dst: &'a mut [MaybeUninit]) -> &'a [u8] { assert_eq!(dst.len(), self.cmsg_space()); @@ -287,3 +290,193 @@ impl<'a> Iterator for ControlMessagesIter<'a> { }) } } + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub struct AncillaryData<'a, 'fd> { + buf: &'a (), + fds: &'fd (), +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub struct AncillaryDataNoCapacity { + p: (), +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +impl Drop for AncillaryData<'_, '_> { + fn drop(&mut self) { + todo!() + } +} + +impl<'a, 'fd> AncillaryData<'a, 'fd> { + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn new(control_messages_buf: &'a mut [MaybeUninit]) -> AncillaryData<'a, 'fd> { + todo!() + } + + // returns initialized portion of `control_messages_buf`. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn control_messages(&self) -> &ControlMessages { + todo!() + } + + // copy a control message into the ancillary data; error on out-of-capacity. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn add_control_message<'b>( + &mut self, + control_message: impl Into>, + ) -> Result<(), AncillaryDataNoCapacity> { + todo!() + } + + // Add an `SCM_RIGHTS` control message with given borrowed FDs. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn add_file_descriptors( + &mut self, + borrowed_fds: &[BorrowedFd<'fd>], + ) -> Result<(), AncillaryDataNoCapacity> { + todo!() + } + + // Transfers ownership of received FDs to the iterator. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn received_fds(&mut self) -> AncillaryDataReceivedFds<'_> { + todo!() + } + + // Obtain a mutable buffer usable as the `msg_control` pointer in a call + // to `sendmsg()` or `recvmsg()`. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn control_messages_buf(&mut self) -> Option<&mut [u8]> { + todo!() + } + + // Update the control messages buffer length according to the result of + // calling `sendmsg()` or `recvmsg()`. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn set_control_messages_len(&mut self, len: usize) { + todo!() + } + + // Scan the control messages buffer for `SCM_RIGHTS` and take ownership of + // any file descriptors found within. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub unsafe fn take_ownership_of_scm_rights(&mut self) { + todo!() + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub struct AncillaryDataReceivedFds<'a> { + buf: &'a mut [u8], +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +impl<'a> Iterator for AncillaryDataReceivedFds<'a> { + type Item = OwnedFd; + + fn next(&mut self) -> Option { + todo!() + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub struct AncillaryDataBuf<'fd> { + borrowed_fds: core::marker::PhantomData<[BorrowedFd<'fd>]>, +} + +impl<'fd> AncillaryDataBuf<'fd> { + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn new<'a>() -> AncillaryDataBuf<'a> { + todo!() + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn with_capacity<'a>(capacity: usize) -> AncillaryDataBuf<'a> { + todo!() + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn capacity(&self) -> usize { + todo!() + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn control_messages(&self) -> &ControlMessages { + todo!() + } + + // copy a control message into the ancillary data; panic on alloc failure. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn add_control_message<'a>(&mut self, control_message: impl Into>) { + todo!() + } + + // Add an `SCM_RIGHTS` control message with given borrowed FDs; panic on + // alloc failure. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn add_file_descriptors(&mut self, borrowed_fds: &[BorrowedFd<'fd>]) { + todo!() + } + + // Used to obtain `AncillaryData` for passing to send/recv calls. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn to_ancillary_data(&mut self) -> AncillaryData<'_, 'fd> { + todo!() + } + + // Clears the control message buffer, without affecting capacity. + // + // This will not leak FDs because the `AncillaryData` type holds a mutable + // reference to the `AncillaryDataBuf`, so if `clear()` is called then there + // are no outstanding `AncillaryData`s and thus no received FDs. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn clear(&mut self) { + todo!() + } + + // as in Vec + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn reserve(&mut self, capacity: usize) { + todo!() + } + + // as in Vec + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn reserve_exact(&mut self, capacity: usize) { + todo!() + } + + // as in Vec + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn try_reserve(&mut self, capacity: usize) -> Result<(), TryReserveError> { + todo!() + } + + // as in Vec + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn try_reserve_exact(&mut self, capacity: usize) -> Result<(), TryReserveError> { + todo!() + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +impl<'a> Extend> for AncillaryDataBuf<'_> { + fn extend(&mut self, iter: I) + where + I: core::iter::IntoIterator>, + { + todo!() + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +impl<'a> Extend<&'a ControlMessage<'a>> for AncillaryDataBuf<'_> { + fn extend(&mut self, iter: I) + where + I: core::iter::IntoIterator>, + { + todo!() + } +} diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index 4f68db2d5d03e..4c97a84d1ed22 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -1,3 +1,5 @@ +use super::ancillary::AncillaryData; +use super::message; use super::{sockaddr_un, SocketAddr}; use crate::net::Shutdown; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; @@ -799,3 +801,84 @@ impl AsInner for UnixDatagram { &self.0 } } + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +impl message::SendMessage for UnixDatagram { + fn send_message( + &self, + bufs: &[io::IoSlice<'_>], + ancillary_data: &mut AncillaryData<'_, '_>, + options: message::SendOptions, + ) -> io::Result { + let mut msg: libc::msghdr = unsafe { core::mem::zeroed() }; + msg.msg_iov = bufs.as_ptr().cast_mut().cast(); + msg.msg_iovlen = bufs.len(); + if let Some(ancillary_buf) = ancillary_data.control_messages_buf() { + msg.msg_control = ancillary_buf.as_mut_ptr().cast(); + msg.msg_controllen = ancillary_buf.len(); + } + let size = self.0.send_msg(&mut msg, options.as_sendmsg_flags())?; + ancillary_data.set_control_messages_len(msg.msg_controllen); + Ok(size) + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +impl message::SendMessageTo for UnixDatagram { + type SocketAddr = SocketAddr; + + fn send_message_to( + &self, + addr: &Self::SocketAddr, + bufs: &[io::IoSlice<'_>], + ancillary_data: &mut AncillaryData<'_, '_>, + options: message::SendOptions, + ) -> io::Result { + let _ = addr; + let _ = bufs; + let _ = ancillary_data; + let _ = options; + todo!() + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +impl message::RecvMessage for UnixDatagram { + fn recv_message( + &self, + bufs: &mut [io::IoSliceMut<'_>], + ancillary_data: &mut AncillaryData<'_, '_>, + options: message::RecvOptions, + ) -> io::Result<(usize, message::MessageFlags)> { + let mut msg: libc::msghdr = unsafe { core::mem::zeroed() }; + msg.msg_iov = bufs.as_mut_ptr().cast(); + msg.msg_iovlen = bufs.len() as _; + if let Some(ancillary_buf) = ancillary_data.control_messages_buf() { + msg.msg_control = ancillary_buf.as_mut_ptr().cast(); + msg.msg_controllen = ancillary_buf.len(); + } + let size = self.0.recv_msg(&mut msg, options.as_recvmsg_flags())?; + ancillary_data.set_control_messages_len(msg.msg_controllen); + unsafe { + ancillary_data.take_ownership_of_scm_rights(); + }; + Ok((size, message::MessageFlags::from_raw(msg.msg_flags))) + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +impl message::RecvMessageFrom for UnixDatagram { + type SocketAddr = SocketAddr; + + fn recv_message_from( + &self, + bufs: &mut [io::IoSliceMut<'_>], + ancillary_data: &mut AncillaryData<'_, '_>, + options: message::RecvOptions, + ) -> io::Result<(usize, message::MessageFlags, Self::SocketAddr)> { + let _ = bufs; + let _ = ancillary_data; + let _ = options; + todo!() + } +} diff --git a/library/std/src/os/unix/net/message.rs b/library/std/src/os/unix/net/message.rs new file mode 100644 index 0000000000000..19b03431ef869 --- /dev/null +++ b/library/std/src/os/unix/net/message.rs @@ -0,0 +1,341 @@ +#![allow(dead_code, unused_imports, unused_variables)] + +use super::ancillary::AncillaryData; +use crate::ffi::c_int; +use crate::io::{self, IoSlice, IoSliceMut}; + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub trait SendMessage { + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + fn send_message( + &self, + bufs: &[IoSlice<'_>], + ancillary_data: &mut AncillaryData<'_, '_>, + options: SendOptions, + ) -> io::Result; +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub trait SendMessageTo { + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + type SocketAddr; + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + fn send_message_to( + &self, + addr: &Self::SocketAddr, + bufs: &[IoSlice<'_>], + ancillary_data: &mut AncillaryData<'_, '_>, + options: SendOptions, + ) -> io::Result; +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +#[derive(Copy, Clone)] +pub struct SendOptions { + bits: c_int, +} + +impl SendOptions { + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn new() -> SendOptions { + SendOptions { bits: 0 } + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn as_send_flags(&self) -> c_int { + self.bits + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn as_sendmsg_flags(&self) -> c_int { + self.bits + } + + // https://doc.rust-lang.org/std/os/unix/fs/trait.OpenOptionsExt.html + // custom_flags(&mut self, flags: i32) -> &mut Self + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn set_eor(&mut self, eor: bool) -> &mut Self { + let _ = eor; + todo!() + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn set_eob(&mut self, eob: bool) -> &mut Self { + let _ = eob; + todo!() + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn set_no_signal(&mut self, no_signal: bool) -> &mut Self { + let _ = no_signal; + todo!() + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +impl Default for SendOptions { + fn default() -> SendOptions { + SendOptions::new() + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub struct MessageSender<'a, 'fd> { + buf: SenderBuf<'a>, + options: SendOptions, + ancillary_data: Option<&'a mut AncillaryData<'a, 'fd>>, +} + +#[derive(Copy, Clone)] +enum SenderBuf<'a> { + Buf([IoSlice<'a>; 1]), + Bufs(&'a [IoSlice<'a>]), +} + +impl<'a> SenderBuf<'a> { + fn get(&self) -> &[IoSlice<'a>] { + match self { + SenderBuf::Buf(ref buf) => buf, + SenderBuf::Bufs(bufs) => bufs, + } + } +} + +impl<'a, 'fd> MessageSender<'a, 'fd> { + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn new(buf: &'a [u8]) -> MessageSender<'a, 'fd> { + MessageSender { + buf: SenderBuf::Buf([IoSlice::new(buf)]), + options: SendOptions::new(), + ancillary_data: None, + } + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn new_vectored(bufs: &'a [IoSlice<'a>]) -> MessageSender<'a, 'fd> { + MessageSender { + buf: SenderBuf::Bufs(bufs), + options: SendOptions::new(), + ancillary_data: None, + } + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn ancillary_data( + &mut self, + ancillary_data: &'a mut AncillaryData<'a, 'fd>, + ) -> &mut MessageSender<'a, 'fd> { + self.ancillary_data = Some(ancillary_data); + self + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn send(&mut self, socket: &S) -> io::Result { + let mut ancillary_empty = AncillaryData::new(&mut []); + let ancillary_data = match self.ancillary_data { + Some(ref mut x) => x, + None => &mut ancillary_empty, + }; + socket.send_message(self.buf.get(), ancillary_data, self.options) + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn send_to( + &mut self, + socket: &S, + addr: &S::SocketAddr, + ) -> io::Result { + let mut ancillary_empty = AncillaryData::new(&mut []); + let ancillary_data = match self.ancillary_data { + Some(ref mut x) => x, + None => &mut ancillary_empty, + }; + socket.send_message_to(addr, self.buf.get(), ancillary_data, self.options) + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub trait RecvMessage { + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + fn recv_message( + &self, + bufs: &mut [IoSliceMut<'_>], + ancillary_data: &mut AncillaryData<'_, '_>, + options: RecvOptions, + ) -> io::Result<(usize, MessageFlags)>; +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub trait RecvMessageFrom { + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + type SocketAddr; + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + fn recv_message_from( + &self, + bufs: &mut [IoSliceMut<'_>], + ancillary_data: &mut AncillaryData<'_, '_>, + options: RecvOptions, + ) -> io::Result<(usize, MessageFlags, Self::SocketAddr)>; +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +#[derive(Copy, Clone)] +pub struct RecvOptions { + bits: c_int, +} + +impl RecvOptions { + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn new() -> RecvOptions { + RecvOptions { bits: 0 } + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn as_recv_flags(&self) -> c_int { + self.bits + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn as_recvmsg_flags(&self) -> c_int { + self.bits | libc::MSG_CMSG_CLOEXEC + } + + // https://doc.rust-lang.org/std/os/unix/fs/trait.OpenOptionsExt.html + // custom_flags(&mut self, flags: i32) -> &mut Self + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn set_oob(&mut self, oob: bool) -> &mut Self { + let _ = oob; + todo!() + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn set_peek(&mut self, peek: bool) -> &mut Self { + let _ = peek; + todo!() + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn set_waitall(&mut self, waitall: bool) -> &mut Self { + let _ = waitall; + todo!() + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +impl Default for RecvOptions { + fn default() -> RecvOptions { + RecvOptions::new() + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +#[derive(Copy, Clone)] +pub struct MessageFlags { + raw: c_int, +} + +impl MessageFlags { + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn from_raw(raw: c_int) -> MessageFlags { + MessageFlags { raw } + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn end_of_record(&self) -> bool { + todo!() + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn oob_received(&self) -> bool { + todo!() + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn normal_data_truncated(&self) -> bool { + todo!() + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn control_data_truncated(&self) -> bool { + todo!() + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub struct MessageReceiver<'a> { + buf: ReceiverBuf<'a>, + options: RecvOptions, + ancillary_data: Option<&'a mut AncillaryData<'a, 'static>>, +} + +enum ReceiverBuf<'a> { + Buf([IoSliceMut<'a>; 1]), + Bufs(&'a mut [IoSliceMut<'a>]), +} + +impl<'a> ReceiverBuf<'a> { + fn get(&mut self) -> &mut [IoSliceMut<'a>] { + match self { + ReceiverBuf::Buf(ref mut buf) => buf, + ReceiverBuf::Bufs(bufs) => bufs, + } + } +} + +impl<'a> MessageReceiver<'a> { + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn new(buf: &'a mut [u8]) -> MessageReceiver<'a> { + Self { + buf: ReceiverBuf::Buf([IoSliceMut::new(buf)]), + options: RecvOptions::new(), + ancillary_data: None, + } + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn new_vectored(bufs: &'a mut [IoSliceMut<'a>]) -> MessageReceiver<'a> { + Self { buf: ReceiverBuf::Bufs(bufs), options: RecvOptions::new(), ancillary_data: None } + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn options(&mut self, options: RecvOptions) -> &mut MessageReceiver<'a> { + self.options = options; + self + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn ancillary_data( + &mut self, + ancillary_data: &'a mut AncillaryData<'a, 'static>, + ) -> &mut MessageReceiver<'a> { + self.ancillary_data = Some(ancillary_data); + self + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn recv(&mut self, socket: &S) -> io::Result<(usize, MessageFlags)> { + let mut ancillary_empty = AncillaryData::new(&mut []); + let ancillary_data = match self.ancillary_data { + Some(ref mut x) => x, + None => &mut ancillary_empty, + }; + socket.recv_message(self.buf.get(), ancillary_data, self.options) + } + + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn recv_from( + &mut self, + socket: &S, + ) -> io::Result<(usize, MessageFlags, S::SocketAddr)> { + let mut ancillary_empty = AncillaryData::new(&mut []); + let ancillary_data = match self.ancillary_data { + Some(ref mut x) => x, + None => &mut ancillary_empty, + }; + socket.recv_message_from(self.buf.get(), ancillary_data, self.options) + } +} diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs index 5035d2f902bab..9c2894cf48838 100644 --- a/library/std/src/os/unix/net/mod.rs +++ b/library/std/src/os/unix/net/mod.rs @@ -9,6 +9,7 @@ mod addr; mod ancillary; mod datagram; mod listener; +mod message; mod stream; #[cfg(all(test, not(target_os = "emscripten")))] mod tests; @@ -21,5 +22,7 @@ pub use self::ancillary::*; pub use self::datagram::*; #[stable(feature = "unix_socket", since = "1.10.0")] pub use self::listener::*; +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub use self::message::*; #[stable(feature = "unix_socket", since = "1.10.0")] pub use self::stream::*; diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index 8ebac1d92a3e5..728796fd8ea40 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -1,3 +1,5 @@ +use super::ancillary::AncillaryData; +use super::message; use super::{sockaddr_un, SocketAddr}; use crate::fmt; use crate::io::{self, IoSlice, IoSliceMut}; @@ -622,3 +624,48 @@ impl AsInner for UnixStream { &self.0 } } + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +impl message::SendMessage for UnixStream { + fn send_message( + &self, + bufs: &[io::IoSlice<'_>], + ancillary_data: &mut AncillaryData<'_, '_>, + options: message::SendOptions, + ) -> io::Result { + let mut msg: libc::msghdr = unsafe { core::mem::zeroed() }; + msg.msg_iov = bufs.as_ptr().cast_mut().cast(); + msg.msg_iovlen = bufs.len() as _; + if let Some(ancillary_buf) = ancillary_data.control_messages_buf() { + msg.msg_control = ancillary_buf.as_mut_ptr().cast(); + msg.msg_controllen = ancillary_buf.len(); + } + let size = self.0.send_msg(&mut msg, options.as_sendmsg_flags())?; + ancillary_data.set_control_messages_len(msg.msg_controllen); + Ok(size) + } +} + +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +impl message::RecvMessage for UnixStream { + fn recv_message( + &self, + bufs: &mut [io::IoSliceMut<'_>], + ancillary_data: &mut AncillaryData<'_, '_>, + options: message::RecvOptions, + ) -> io::Result<(usize, message::MessageFlags)> { + let mut msg: libc::msghdr = unsafe { core::mem::zeroed() }; + msg.msg_iov = bufs.as_mut_ptr().cast(); + msg.msg_iovlen = bufs.len() as _; + if let Some(ancillary_buf) = ancillary_data.control_messages_buf() { + msg.msg_control = ancillary_buf.as_mut_ptr().cast(); + msg.msg_controllen = ancillary_buf.len(); + } + let size = self.0.recv_msg(&mut msg, options.as_recvmsg_flags())?; + ancillary_data.set_control_messages_len(msg.msg_controllen); + unsafe { + ancillary_data.take_ownership_of_scm_rights(); + }; + Ok((size, message::MessageFlags::from_raw(msg.msg_flags))) + } +} diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index 7bc591b1df87a..85d1f96a5f73c 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -327,9 +327,8 @@ impl Socket { self.recv_from_with_flags(buf, 0) } - #[allow(dead_code)] - pub fn recv_msg(&self, msg: &mut libc::msghdr) -> io::Result { - let n = cvt(unsafe { libc::recvmsg(self.as_raw_fd(), msg, libc::MSG_CMSG_CLOEXEC) })?; + pub fn recv_msg(&self, msg: &mut libc::msghdr, flags: c_int) -> io::Result { + let n = cvt(unsafe { libc::recvmsg(self.as_raw_fd(), msg, flags) })?; Ok(n as usize) } @@ -350,9 +349,8 @@ impl Socket { self.0.is_write_vectored() } - #[allow(dead_code)] - pub fn send_msg(&self, msg: &mut libc::msghdr) -> io::Result { - let n = cvt(unsafe { libc::sendmsg(self.as_raw_fd(), msg, 0) })?; + pub fn send_msg(&self, msg: &mut libc::msghdr, flags: c_int) -> io::Result { + let n = cvt(unsafe { libc::sendmsg(self.as_raw_fd(), msg, flags) })?; Ok(n as usize) }