diff --git a/CHANGES.md b/CHANGES.md index f3eadf2a6..61e937d44 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -267,5 +267,11 @@ argument optionallly containing a raw file descriptor. [`rustix::io_uring::io_uring_setup`]: https://docs.rs/rustix/1.0.0/rustix/io_uring/fn.io_uring_setup.html +The buffer for [`SendAncillaryBuffer`] and [`RecvAncillaryBuffer`] is now +a `[MaybeUninit]` instead of a `[u8]`. + +[`SendAncillaryBuffer`]: https://docs.rs/rustix/1.0.0/rustix/net/struct.SendAncillaryBuffer.html +[`RecvAncillaryBuffer`]: https://docs.rs/rustix/1.0.0/rustix/net/struct.RecvAncillaryBuffer.html + All explicitly deprecated functions and types have been removed. Their deprecation messages will have identified alternatives. diff --git a/src/net/send_recv/msg.rs b/src/net/send_recv/msg.rs index 20510d47e..fe03574b3 100644 --- a/src/net/send_recv/msg.rs +++ b/src/net/send_recv/msg.rs @@ -14,7 +14,7 @@ use crate::net::UCred; use core::fmt; use core::iter::FusedIterator; use core::marker::PhantomData; -use core::mem::{align_of, size_of, size_of_val, take}; +use core::mem::{align_of, size_of, size_of_val, take, MaybeUninit}; #[cfg(linux_kernel)] use core::ptr::addr_of; use core::{ptr, slice}; @@ -28,16 +28,20 @@ use super::{RecvFlags, ReturnFlags, SendFlags, SocketAddrAny}; /// /// Allocate a buffer for a single file descriptor: /// ``` +/// # use core::mem::MaybeUninit; /// # use rustix::cmsg_space; -/// let mut space = [0; rustix::cmsg_space!(ScmRights(1))]; +/// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(1))]; +/// # let _: &[MaybeUninit] = space.as_slice(); /// ``` /// /// Allocate a buffer for credentials: /// ``` /// # #[cfg(linux_kernel)] /// # { +/// # use core::mem::MaybeUninit; /// # use rustix::cmsg_space; -/// let mut space = [0; rustix::cmsg_space!(ScmCredentials(1))]; +/// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmCredentials(1))]; +/// # let _: &[MaybeUninit] = space.as_slice(); /// # } /// ``` /// @@ -45,8 +49,10 @@ use super::{RecvFlags, ReturnFlags, SendFlags, SocketAddrAny}; /// ``` /// # #[cfg(linux_kernel)] /// # { +/// # use core::mem::MaybeUninit; /// # use rustix::cmsg_space; -/// let mut space = [0; rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))]; +/// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))]; +/// # let _: &[MaybeUninit] = space.as_slice(); /// # } /// ``` #[macro_export] @@ -169,7 +175,7 @@ pub enum RecvAncillaryMessage<'a> { /// [`push`]: SendAncillaryBuffer::push pub struct SendAncillaryBuffer<'buf, 'slice, 'fd> { /// Raw byte buffer for messages. - buffer: &'buf mut [u8], + buffer: &'buf mut [MaybeUninit], /// The amount of the buffer that is used. length: usize, @@ -178,8 +184,8 @@ pub struct SendAncillaryBuffer<'buf, 'slice, 'fd> { _phantom: PhantomData<&'slice [BorrowedFd<'fd>]>, } -impl<'buf> From<&'buf mut [u8]> for SendAncillaryBuffer<'buf, '_, '_> { - fn from(buffer: &'buf mut [u8]) -> Self { +impl<'buf> From<&'buf mut [MaybeUninit]> for SendAncillaryBuffer<'buf, '_, '_> { + fn from(buffer: &'buf mut [MaybeUninit]) -> Self { Self::new(buffer) } } @@ -205,9 +211,10 @@ impl<'buf, 'slice, 'fd> SendAncillaryBuffer<'buf, 'slice, 'fd> { /// /// Allocate a buffer for a single file descriptor: /// ``` + /// # use core::mem::MaybeUninit; /// # use rustix::cmsg_space; /// # use rustix::net::SendAncillaryBuffer; - /// let mut space = [0; rustix::cmsg_space!(ScmRights(1))]; + /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(1))]; /// let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); /// ``` /// @@ -215,9 +222,10 @@ impl<'buf, 'slice, 'fd> SendAncillaryBuffer<'buf, 'slice, 'fd> { /// ``` /// # #[cfg(linux_kernel)] /// # { + /// # use core::mem::MaybeUninit; /// # use rustix::cmsg_space; /// # use rustix::net::SendAncillaryBuffer; - /// let mut space = [0; rustix::cmsg_space!(ScmCredentials(1))]; + /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmCredentials(1))]; /// let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); /// # } /// ``` @@ -226,16 +234,17 @@ impl<'buf, 'slice, 'fd> SendAncillaryBuffer<'buf, 'slice, 'fd> { /// ``` /// # #[cfg(linux_kernel)] /// # { + /// # use core::mem::MaybeUninit; /// # use rustix::cmsg_space; /// # use rustix::net::SendAncillaryBuffer; - /// let mut space = [0; rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))]; + /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))]; /// let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); /// # } /// ``` /// /// [`send`]: crate::net::send #[inline] - pub fn new(buffer: &'buf mut [u8]) -> Self { + pub fn new(buffer: &'buf mut [MaybeUninit]) -> Self { Self { buffer: align_for_cmsghdr(buffer), length: 0, @@ -253,7 +262,7 @@ impl<'buf, 'slice, 'fd> SendAncillaryBuffer<'buf, 'slice, 'fd> { return core::ptr::null_mut(); } - self.buffer.as_mut_ptr() + self.buffer.as_mut_ptr().cast() } /// Returns the length of the message data. @@ -306,7 +315,7 @@ impl<'buf, 'slice, 'fd> SendAncillaryBuffer<'buf, 'slice, 'fd> { let buffer = leap!(self.buffer.get_mut(..new_length)); // Fill the new part of the buffer with zeroes. - buffer[self.length..new_length].fill(0); + buffer[self.length..new_length].fill(MaybeUninit::new(0)); self.length = new_length; // Get the last header in the buffer. @@ -344,7 +353,7 @@ impl<'slice, 'fd> Extend> #[derive(Default)] pub struct RecvAncillaryBuffer<'buf> { /// Raw byte buffer for messages. - buffer: &'buf mut [u8], + buffer: &'buf mut [MaybeUninit], /// The portion of the buffer we've read from already. read: usize, @@ -353,8 +362,8 @@ pub struct RecvAncillaryBuffer<'buf> { length: usize, } -impl<'buf> From<&'buf mut [u8]> for RecvAncillaryBuffer<'buf> { - fn from(buffer: &'buf mut [u8]) -> Self { +impl<'buf> From<&'buf mut [MaybeUninit]> for RecvAncillaryBuffer<'buf> { + fn from(buffer: &'buf mut [MaybeUninit]) -> Self { Self::new(buffer) } } @@ -370,9 +379,10 @@ impl<'buf> RecvAncillaryBuffer<'buf> { /// /// Allocate a buffer for a single file descriptor: /// ``` + /// # use core::mem::MaybeUninit; /// # use rustix::cmsg_space; /// # use rustix::net::RecvAncillaryBuffer; - /// let mut space = [0; rustix::cmsg_space!(ScmRights(1))]; + /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(1))]; /// let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut space); /// ``` /// @@ -380,9 +390,10 @@ impl<'buf> RecvAncillaryBuffer<'buf> { /// ``` /// # #[cfg(linux_kernel)] /// # { + /// # use core::mem::MaybeUninit; /// # use rustix::cmsg_space; /// # use rustix::net::RecvAncillaryBuffer; - /// let mut space = [0; rustix::cmsg_space!(ScmCredentials(1))]; + /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmCredentials(1))]; /// let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut space); /// # } /// ``` @@ -391,16 +402,17 @@ impl<'buf> RecvAncillaryBuffer<'buf> { /// ``` /// # #[cfg(linux_kernel)] /// # { + /// # use core::mem::MaybeUninit; /// # use rustix::cmsg_space; /// # use rustix::net::RecvAncillaryBuffer; - /// let mut space = [0; rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))]; + /// let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(2), ScmCredentials(1))]; /// let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut space); /// # } /// ``` /// /// [`recv`]: crate::net::recv #[inline] - pub fn new(buffer: &'buf mut [u8]) -> Self { + pub fn new(buffer: &'buf mut [MaybeUninit]) -> Self { Self { buffer: align_for_cmsghdr(buffer), read: 0, @@ -418,7 +430,7 @@ impl<'buf> RecvAncillaryBuffer<'buf> { return core::ptr::null_mut(); } - self.buffer.as_mut_ptr() + self.buffer.as_mut_ptr().cast() } /// Returns the length of the message data. @@ -459,7 +471,7 @@ impl Drop for RecvAncillaryBuffer<'_> { /// Return a slice of `buffer` starting at the first `cmsghdr` alignment /// boundary. #[inline] -fn align_for_cmsghdr(buffer: &mut [u8]) -> &mut [u8] { +fn align_for_cmsghdr(buffer: &mut [MaybeUninit]) -> &mut [MaybeUninit] { // If the buffer is empty, we won't be writing anything into it, so it // doesn't need to be aligned. if buffer.is_empty() { @@ -884,6 +896,7 @@ mod messages { use crate::backend::net::msghdr; use core::iter::FusedIterator; use core::marker::PhantomData; + use core::mem::MaybeUninit; use core::ptr::NonNull; /// An iterator over the messages in an ancillary buffer. @@ -897,15 +910,19 @@ mod messages { header: Option>, /// Capture the original lifetime of the buffer. - _buffer: PhantomData<&'buf mut [u8]>, + _buffer: PhantomData<&'buf mut [MaybeUninit]>, } + pub(super) trait AllowedMsgBufType {} + impl AllowedMsgBufType for u8 {} + impl AllowedMsgBufType for MaybeUninit {} + impl<'buf> Messages<'buf> { /// Create a new iterator over messages from a byte buffer. - pub(super) fn new(buf: &'buf mut [u8]) -> Self { + pub(super) fn new(buf: &'buf mut [impl AllowedMsgBufType]) -> Self { let mut msghdr = msghdr::zero_msghdr(); msghdr.msg_control = buf.as_mut_ptr().cast(); - msghdr.msg_controllen = buf.len().try_into().unwrap(); + msghdr.msg_controllen = buf.len().try_into().expect("buffer too large for msghdr"); // Get the first header. let header = NonNull::new(unsafe { c::CMSG_FIRSTHDR(&msghdr) }); diff --git a/tests/net/unix.rs b/tests/net/unix.rs index ca107c8bc..a04298610 100644 --- a/tests/net/unix.rs +++ b/tests/net/unix.rs @@ -13,6 +13,7 @@ use rustix::net::{ accept, bind, connect, listen, socket, AddressFamily, SocketAddrUnix, SocketType, }; use rustix::path::DecInt; +use std::mem::MaybeUninit; use std::path::Path; use std::str::FromStr as _; use std::sync::{Arc, Condvar, Mutex}; @@ -449,13 +450,13 @@ fn test_unix_msg_with_scm_rights() { let mut pipe_end = None; let mut buffer = [0; BUFFER_SIZE]; - let mut cmsg_space = [0; rustix::cmsg_space!(ScmRights(1))]; + let mut cmsg_space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(1))]; 'exit: loop { let data_socket = accept(&connection_socket).unwrap(); let mut sum = 0; loop { - let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut cmsg_space); + let mut cmsg_buffer = RecvAncillaryBuffer::new(cmsg_space.as_mut_slice()); let result = recvmsg( &data_socket, &mut [IoSliceMut::new(&mut buffer)], @@ -560,8 +561,8 @@ fn test_unix_msg_with_scm_rights() { // Format the CMSG. let we = [write_end.as_fd()]; let msg = SendAncillaryMessage::ScmRights(&we); - let mut space = [0; rustix::cmsg_space!(ScmRights(1))]; - let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); + let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(1))]; + let mut cmsg_buffer = SendAncillaryBuffer::new(space.as_mut_slice()); assert!(cmsg_buffer.push(msg)); connect(&data_socket, &addr).unwrap(); @@ -620,8 +621,8 @@ fn test_unix_peercred_explicit() { let ucred = sockopt::socket_peercred(&send_sock).unwrap(); let msg = SendAncillaryMessage::ScmCredentials(ucred); - let mut space = [0; rustix::cmsg_space!(ScmCredentials(1))]; - let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); + let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmCredentials(1))]; + let mut cmsg_buffer = SendAncillaryBuffer::new(space.as_mut_slice()); assert!(cmsg_buffer.push(msg)); sendmsg( @@ -632,8 +633,8 @@ fn test_unix_peercred_explicit() { ) .unwrap(); - let mut cmsg_space = [0; rustix::cmsg_space!(ScmCredentials(1))]; - let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut cmsg_space); + let mut cmsg_space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmCredentials(1))]; + let mut cmsg_buffer = RecvAncillaryBuffer::new(cmsg_space.as_mut_slice()); let mut buffer = [0; BUFFER_SIZE]; let result = recvmsg( @@ -692,8 +693,8 @@ fn test_unix_peercred_implicit() { ) .unwrap(); - let mut cmsg_space = [0; rustix::cmsg_space!(ScmCredentials(1))]; - let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut cmsg_space); + let mut cmsg_space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmCredentials(1))]; + let mut cmsg_buffer = RecvAncillaryBuffer::new(cmsg_space.as_mut_slice()); let mut buffer = [0; BUFFER_SIZE]; let result = recvmsg( @@ -747,13 +748,14 @@ fn test_unix_msg_with_combo() { let mut yet_another_pipe_end = None; let mut buffer = [0; BUFFER_SIZE]; - let mut cmsg_space = [0; rustix::cmsg_space!(ScmRights(2), ScmRights(1))]; + let mut cmsg_space = + [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(2), ScmRights(1))]; 'exit: loop { let data_socket = accept(&connection_socket).unwrap(); let mut sum = 0; loop { - let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut cmsg_space); + let mut cmsg_buffer = RecvAncillaryBuffer::new(cmsg_space.as_mut_slice()); let result = recvmsg( &data_socket, &mut [IoSliceMut::new(&mut buffer)], @@ -872,8 +874,8 @@ fn test_unix_msg_with_combo() { let data_socket = socket(AddressFamily::UNIX, SocketType::SEQPACKET, None).unwrap(); - let mut space = [0; rustix::cmsg_space!(ScmRights(2), ScmRights(1))]; - let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); + let mut space = [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(2), ScmRights(1))]; + let mut cmsg_buffer = SendAncillaryBuffer::new(space.as_mut_slice()); // Format a CMSG. let we = [write_end.as_fd(), another_write_end.as_fd()]; diff --git a/tests/net/unix_alloc.rs b/tests/net/unix_alloc.rs index 0e8aa0310..c8ecc9731 100644 --- a/tests/net/unix_alloc.rs +++ b/tests/net/unix_alloc.rs @@ -447,13 +447,13 @@ fn test_unix_msg_with_scm_rights() { let mut pipe_end = None; let mut buffer = vec![0; BUFFER_SIZE]; - let mut cmsg_space = vec![0; rustix::cmsg_space!(ScmRights(1))]; + let mut cmsg_space = Vec::with_capacity(rustix::cmsg_space!(ScmRights(1))); 'exit: loop { let data_socket = accept(&connection_socket).unwrap(); let mut sum = 0; loop { - let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut cmsg_space); + let mut cmsg_buffer = RecvAncillaryBuffer::new(cmsg_space.spare_capacity_mut()); let result = recvmsg( &data_socket, &mut [IoSliceMut::new(&mut buffer)], @@ -558,8 +558,8 @@ fn test_unix_msg_with_scm_rights() { // Format the CMSG. let we = [write_end.as_fd()]; let msg = SendAncillaryMessage::ScmRights(&we); - let mut space = vec![0; msg.size()]; - let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); + let mut space = Vec::with_capacity(msg.size()); + let mut cmsg_buffer = SendAncillaryBuffer::new(space.spare_capacity_mut()); assert!(cmsg_buffer.push(msg)); connect(&data_socket, &addr).unwrap(); @@ -623,8 +623,8 @@ fn test_unix_peercred() { assert_eq!(ucred.gid, getgid()); let msg = SendAncillaryMessage::ScmCredentials(ucred); - let mut space = vec![0; msg.size()]; - let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); + let mut space = Vec::with_capacity(msg.size()); + let mut cmsg_buffer = SendAncillaryBuffer::new(space.spare_capacity_mut()); assert!(cmsg_buffer.push(msg)); sendmsg( @@ -635,8 +635,8 @@ fn test_unix_peercred() { ) .unwrap(); - let mut cmsg_space = vec![0; rustix::cmsg_space!(ScmCredentials(1))]; - let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut cmsg_space); + let mut cmsg_space = Vec::with_capacity(rustix::cmsg_space!(ScmCredentials(1))); + let mut cmsg_buffer = RecvAncillaryBuffer::new(cmsg_space.spare_capacity_mut()); let mut buffer = vec![0; BUFFER_SIZE]; recvmsg( @@ -688,13 +688,14 @@ fn test_unix_msg_with_combo() { let mut yet_another_pipe_end = None; let mut buffer = vec![0; BUFFER_SIZE]; - let mut cmsg_space = vec![0; rustix::cmsg_space!(ScmRights(1), ScmRights(2))]; + let mut cmsg_space = + Vec::with_capacity(rustix::cmsg_space!(ScmRights(1), ScmRights(2))); 'exit: loop { let data_socket = accept(&connection_socket).unwrap(); let mut sum = 0; loop { - let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut cmsg_space); + let mut cmsg_buffer = RecvAncillaryBuffer::new(cmsg_space.spare_capacity_mut()); let result = recvmsg( &data_socket, &mut [IoSliceMut::new(&mut buffer)], @@ -813,8 +814,8 @@ fn test_unix_msg_with_combo() { let data_socket = socket(AddressFamily::UNIX, SocketType::SEQPACKET, None).unwrap(); - let mut space = vec![0; rustix::cmsg_space!(ScmRights(1), ScmRights(2))]; - let mut cmsg_buffer = SendAncillaryBuffer::new(&mut space); + let mut space = Vec::with_capacity(rustix::cmsg_space!(ScmRights(1), ScmRights(2))); + let mut cmsg_buffer = SendAncillaryBuffer::new(space.spare_capacity_mut()); // Format a CMSG. let we = [write_end.as_fd(), another_write_end.as_fd()];