-
Notifications
You must be signed in to change notification settings - Fork 256
Expand file tree
/
Copy pathnetbsd.rs
More file actions
49 lines (43 loc) · 1.49 KB
/
netbsd.rs
File metadata and controls
49 lines (43 loc) · 1.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//! Implementation for NetBSD
use crate::{util_libc::sys_fill_exact, weak::Weak, Error};
use core::{ffi::c_void, mem::MaybeUninit, ptr};
fn kern_arnd(buf: &mut [MaybeUninit<u8>]) -> libc::ssize_t {
static MIB: [libc::c_int; 2] = [libc::CTL_KERN, libc::KERN_ARND];
let mut len = buf.len();
let ret = unsafe {
libc::sysctl(
MIB.as_ptr(),
MIB.len() as libc::c_uint,
buf.as_mut_ptr() as *mut _,
&mut len,
ptr::null(),
0,
)
};
if ret == -1 {
-1
} else {
len as libc::ssize_t
}
}
type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t;
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
fn link_getrandom() -> *mut c_void {
static NAME: &[u8] = b"getrandom\0";
unsafe { libc::dlsym(libc::RTLD_DEFAULT, NAME.as_ptr() as *const _) }
}
// getrandom(2) was introduced in NetBSD 10.0
static GETRANDOM: Weak = Weak::new(link_getrandom);
if let Some(fptr) = GETRANDOM.ptr() {
let func: GetRandomFn = unsafe { core::mem::transmute(fptr) };
return sys_fill_exact(dest, |buf| unsafe {
func(buf.as_mut_ptr() as *mut u8, buf.len(), 0)
});
}
// NetBSD will only return up to 256 bytes at a time, and
// older NetBSD kernels will fail on longer buffers.
for chunk in dest.chunks_mut(256) {
sys_fill_exact(chunk, kern_arnd)?
}
Ok(())
}