Skip to content

Commit 61ef72f

Browse files
committed
Use getentropy(2) on macos
1 parent 1057dc9 commit 61ef72f

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

src/libstd/sys/unix/rand.rs

+37
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub fn hashmap_random_keys() -> (u64, u64) {
1212

1313
#[cfg(all(
1414
unix,
15+
not(target_os = "macos"),
1516
not(target_os = "ios"),
1617
not(target_os = "openbsd"),
1718
not(target_os = "freebsd"),
@@ -92,6 +93,42 @@ mod imp {
9293
}
9394
}
9495

96+
#[cfg(target_os = "macos")]
97+
mod imp {
98+
use crate::fs::File;
99+
use crate::io::Read;
100+
use crate::sys::os::errno;
101+
use libc::{c_int, c_void, size_t};
102+
103+
fn getentropy_fill_bytes(v: &mut [u8]) -> bool {
104+
weak!(fn getentropy(*mut c_void, size_t) -> c_int);
105+
106+
getentropy
107+
.get()
108+
.map(|f| {
109+
// getentropy(2) permits a maximum buffer size of 256 bytes
110+
for s in v.chunks_mut(256) {
111+
let ret = unsafe { f(s.as_mut_ptr() as *mut c_void, s.len()) };
112+
if ret == -1 {
113+
panic!("unexpected getentropy error: {}", errno());
114+
}
115+
}
116+
true
117+
})
118+
.unwrap_or(false)
119+
}
120+
121+
pub fn fill_bytes(v: &mut [u8]) {
122+
if getentropy_fill_bytes(v) {
123+
return;
124+
}
125+
126+
// for older macos which doesn't support getentropy
127+
let mut file = File::open("/dev/urandom").expect("failed to open /dev/urandom");
128+
file.read_exact(v).expect("failed to read /dev/urandom")
129+
}
130+
}
131+
95132
#[cfg(target_os = "openbsd")]
96133
mod imp {
97134
use crate::sys::os::errno;

0 commit comments

Comments
 (0)