getrandom/utils/
sys_fill_exact.rs1use crate::Error;
2use core::mem::MaybeUninit;
3
4mod get_errno;
5mod sanitizer;
6
7pub(crate) use get_errno::get_errno;
8
9pub(crate) fn sys_fill_exact(
15 mut buf: &mut [MaybeUninit<u8>],
16 sys_fill: impl Fn(&mut [MaybeUninit<u8>]) -> libc::ssize_t,
17) -> Result<(), Error> {
18 while !buf.is_empty() {
19 let res = sys_fill(buf);
20 match res {
21 res if res > 0 => {
22 let len = usize::try_from(res).map_err(|_| Error::UNEXPECTED)?;
23 let (l, r) = buf.split_at_mut_checked(len).ok_or(Error::UNEXPECTED)?;
24 unsafe { sanitizer::unpoison(l) };
25 buf = r;
26 }
27 -1 => {
28 let errno = get_errno();
29 if errno != libc::EINTR {
31 return Err(Error::from_errno(errno));
32 }
33 }
34 _ => return Err(Error::UNEXPECTED),
38 }
39 }
40 Ok(())
41}