Skip to content

Commit 28e9eca

Browse files
committed
Allow ancillary socket data to be read into an uninitialized buffer.
1 parent 15b6441 commit 28e9eca

File tree

1 file changed

+27
-10
lines changed

1 file changed

+27
-10
lines changed

library/std/src/os/unix/net/ancillary.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ use super::{sockaddr_un, SocketAddr};
22
use crate::convert::TryFrom;
33
use crate::io::{self, IoSlice, IoSliceMut};
44
use crate::marker::PhantomData;
5-
use crate::mem::{size_of, zeroed};
5+
use crate::mem::{size_of, zeroed, MaybeUninit};
66
use crate::os::unix::io::RawFd;
77
use crate::path::Path;
88
use crate::ptr::{eq, read_unaligned};
9-
use crate::slice::from_raw_parts;
9+
use crate::slice;
1010
use crate::sys::net::Socket;
1111

1212
// FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here?
@@ -79,7 +79,7 @@ pub(super) fn send_vectored_with_ancillary_to(
7979
}
8080

8181
fn add_to_ancillary_data<T>(
82-
buffer: &mut [u8],
82+
buffer: &mut [MaybeUninit<u8>],
8383
length: &mut usize,
8484
source: &[T],
8585
cmsg_level: libc::c_int,
@@ -108,7 +108,7 @@ fn add_to_ancillary_data<T>(
108108
return false;
109109
}
110110

111-
buffer[*length..new_length].fill(0);
111+
buffer[*length..new_length].fill(MaybeUninit::new(0));
112112

113113
*length = new_length;
114114

@@ -309,7 +309,7 @@ impl<'a> AncillaryData<'a> {
309309
let cmsg_len_zero = libc::CMSG_LEN(0) as usize;
310310
let data_len = (*cmsg).cmsg_len as usize - cmsg_len_zero;
311311
let data = libc::CMSG_DATA(cmsg).cast();
312-
let data = from_raw_parts(data, data_len);
312+
let data = slice::from_raw_parts(data, data_len);
313313

314314
match (*cmsg).cmsg_level {
315315
libc::SOL_SOCKET => match (*cmsg).cmsg_type {
@@ -401,7 +401,7 @@ impl<'a> Iterator for Messages<'a> {
401401
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
402402
#[derive(Debug)]
403403
pub struct SocketAncillary<'a> {
404-
buffer: &'a mut [u8],
404+
buffer: &'a mut [MaybeUninit<u8>],
405405
length: usize,
406406
truncated: bool,
407407
}
@@ -420,6 +420,23 @@ impl<'a> SocketAncillary<'a> {
420420
/// ```
421421
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
422422
pub fn new(buffer: &'a mut [u8]) -> Self {
423+
let buffer = unsafe { slice::from_raw_parts_mut(buffer.as_mut_ptr().cast(), buffer.len()) };
424+
Self::new_uninit(buffer)
425+
}
426+
427+
/// Create an ancillary data with an uninitialized buffer.
428+
///
429+
/// # Example
430+
///
431+
/// ```no_run
432+
/// # #![allow(unused_mut)]
433+
/// #![feature(unix_socket_ancillary_data, new_uninit)]
434+
/// use std::os::unix::net::SocketAncillary;
435+
/// let mut ancillary_buffer = Box::new_uninit_slice(128);
436+
/// let mut ancillary = SocketAncillary::new_uninit(&mut ancillary_buffer[..]);
437+
/// ```
438+
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
439+
pub fn new_uninit(buffer: &'a mut [MaybeUninit<u8>]) -> Self {
423440
SocketAncillary { buffer, length: 0, truncated: false }
424441
}
425442

@@ -432,14 +449,14 @@ impl<'a> SocketAncillary<'a> {
432449
/// Returns the raw ancillary data as byte slice.
433450
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
434451
pub fn data(&self) -> &[u8] {
435-
&self.buffer[..self.length]
452+
unsafe { MaybeUninit::slice_assume_init_ref(&self.buffer[..self.length]) }
436453
}
437454

438455
/// Returns the entire buffer, including unused capacity.
439456
///
440457
/// Use [`data()`](Self::data) if you are only interested in the used portion of the buffer.
441458
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
442-
pub fn buffer(&self) -> &[u8] {
459+
pub fn buffer(&self) -> &[MaybeUninit<u8>] {
443460
self.buffer
444461
}
445462

@@ -453,7 +470,7 @@ impl<'a> SocketAncillary<'a> {
453470
/// and you must call [`set_len()`](Self::set_len) after changing
454471
/// the buffer contents to update the internal bookkeeping.
455472
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
456-
pub unsafe fn buffer_mut(&mut self) -> &mut [u8] {
473+
pub unsafe fn buffer_mut(&mut self) -> &mut [MaybeUninit<u8>] {
457474
self.buffer
458475
}
459476

@@ -486,7 +503,7 @@ impl<'a> SocketAncillary<'a> {
486503
/// Returns the iterator of the control messages.
487504
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
488505
pub fn messages(&self) -> Messages<'_> {
489-
Messages { buffer: &self.buffer[..self.length], current: None }
506+
Messages { buffer: self.data(), current: None }
490507
}
491508

492509
/// Is `true` if during a recv operation the ancillary was truncated.

0 commit comments

Comments
 (0)