1 #![allow(unsafe_code)]
2
3 use crate::buffer::split_init;
4 use crate::{backend, io};
5 use core::mem::MaybeUninit;
6
7 pub use backend::rand::types::GetRandomFlags;
8
9 /// `getrandom(buf, flags)`—Reads a sequence of random bytes.
10 ///
11 /// This is a very low-level API which may be difficult to use correctly. Most
12 /// users should prefer to use [`getrandom`] or [`rand`] APIs instead.
13 ///
14 /// [`getrandom`]: https://crates.io/crates/getrandom
15 /// [`rand`]: https://crates.io/crates/rand
16 ///
17 /// # References
18 /// - [Linux]
19 ///
20 /// [Linux]: https://man7.org/linux/man-pages/man2/getrandom.2.html
21 #[inline]
getrandom(buf: &mut [u8], flags: GetRandomFlags) -> io::Result<usize>22 pub fn getrandom(buf: &mut [u8], flags: GetRandomFlags) -> io::Result<usize> {
23 unsafe { backend::rand::syscalls::getrandom(buf.as_mut_ptr(), buf.len(), flags) }
24 }
25
26 /// `getrandom(buf, flags)`—Reads a sequence of random bytes.
27 ///
28 /// This is identical to [`getrandom`], except that it can read into
29 /// uninitialized memory. It returns the slice that was initialized by this
30 /// function and the slice that remains uninitialized.
31 #[inline]
getrandom_uninit( buf: &mut [MaybeUninit<u8>], flags: GetRandomFlags, ) -> io::Result<(&mut [u8], &mut [MaybeUninit<u8>])>32 pub fn getrandom_uninit(
33 buf: &mut [MaybeUninit<u8>],
34 flags: GetRandomFlags,
35 ) -> io::Result<(&mut [u8], &mut [MaybeUninit<u8>])> {
36 // Get number of initialized bytes.
37 let length = unsafe {
38 backend::rand::syscalls::getrandom(buf.as_mut_ptr() as *mut u8, buf.len(), flags)
39 };
40
41 // Split into the initialized and uninitialized portions.
42 Ok(unsafe { split_init(buf, length?) })
43 }
44