Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions src/sys/bsd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,18 @@ fn allocate_loop<F: Fn(*mut c_void, size_t) -> libc::ssize_t>(f: F) -> io::Resul
|buf| unsafe {
let (ptr, len) = slice_parts(buf);
let new_len = cvt(f(ptr, len))?;
assert!(
new_len <= len,
"OS returned length {new_len} greater than buffer size {len}"
);
Ok(slice::from_raw_parts_mut(ptr.cast(), new_len))
if new_len < len {
Ok(slice::from_raw_parts_mut(ptr.cast(), new_len))
} else {
// If the length of the value isn't strictly smaller than the length of the value
// read, there may be more to read. Fake an ERANGE error so we can try again with a
// bigger buffer.
Err(io::Error::from_raw_os_error(crate::sys::ERANGE))
}
},
|| cvt(f(ptr::null_mut(), 0)),
// Estimate size + 1 because, on freebsd, the only way to tell if we've read the entire
// value is read a value smaller than the buffer we passed.
|| Ok(cvt(f(ptr::null_mut(), 0))? + 1),
)
}

Expand Down
2 changes: 1 addition & 1 deletion src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ where
S: FnMut() -> io::Result<usize>,
{
// Start by assuming the return value is <= 4KiB. If it is, we can do this in one syscall.
const INITIAL_BUFFER_SIZE: usize = 4096;
const INITIAL_BUFFER_SIZE: usize = 2;
match get_value(&mut [MaybeUninit::<u8>::uninit(); INITIAL_BUFFER_SIZE]) {
Ok(val) => return Ok(val.to_vec()),
Err(e) if e.raw_os_error() != Some(crate::sys::ERANGE) => return Err(e),
Expand Down