1 // Copyright 2018 Developers of the Rand project.
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
9 //! Implementation for Linux / Android
10 use crate::util
::LazyBool
;
11 use crate::util_libc
::{last_os_error, sys_fill_exact}
;
12 use crate::{use_file, Error}
;
14 pub fn getrandom_inner(dest
: &mut [u8]) -> Result
<(), Error
> {
15 static HAS_GETRANDOM
: LazyBool
= LazyBool
::new();
16 if HAS_GETRANDOM
.unsync_init(is_getrandom_available
) {
17 sys_fill_exact(dest
, |buf
| unsafe {
18 getrandom(buf
.as_mut_ptr() as *mut libc
::c_void
, buf
.len(), 0)
21 use_file
::getrandom_inner(dest
)
25 fn is_getrandom_available() -> bool
{
26 let res
= unsafe { getrandom(core::ptr::null_mut(), 0, libc::GRND_NONBLOCK) }
;
28 match last_os_error().raw_os_error() {
29 Some(libc
::ENOSYS
) => false, // No kernel support
30 Some(libc
::EPERM
) => false, // Blocked by seccomp
39 buf
: *mut libc
::c_void
,
43 libc
::syscall(libc
::SYS_getrandom
, buf
, buflen
, flags
) as libc
::ssize_t