xref: /aosp_15_r20/external/cronet/third_party/rust/chromium_crates_io/vendor/getrandom-0.2.14/src/hermit.rs (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 //! Implementation for Hermit
2 use crate::Error;
3 use core::{mem::MaybeUninit, num::NonZeroU32};
4 
5 /// Minimum return value which we should get from syscalls in practice,
6 /// because Hermit uses positive `i32`s for error codes:
7 /// https://github.com/hermitcore/libhermit-rs/blob/main/src/errno.rs
8 const MIN_RET_CODE: isize = -(i32::MAX as isize);
9 
10 extern "C" {
sys_read_entropy(buffer: *mut u8, length: usize, flags: u32) -> isize11     fn sys_read_entropy(buffer: *mut u8, length: usize, flags: u32) -> isize;
12 }
13 
getrandom_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error>14 pub fn getrandom_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
15     while !dest.is_empty() {
16         let res = unsafe { sys_read_entropy(dest.as_mut_ptr() as *mut u8, dest.len(), 0) };
17         // Positive `isize`s can be safely casted to `usize`
18         if res > 0 && (res as usize) <= dest.len() {
19             dest = &mut dest[res as usize..];
20         } else {
21             let err = match res {
22                 MIN_RET_CODE..=-1 => NonZeroU32::new(-res as u32).unwrap().into(),
23                 _ => Error::UNEXPECTED,
24             };
25             return Err(err);
26         }
27     }
28     Ok(())
29 }
30