about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-03-23 04:26:07 +0100
committerGitHub <noreply@github.com>2020-03-23 04:26:07 +0100
commit675bdf6d6d7b6441598961052df6466efbb4bee4 (patch)
treebd706d607298ed2db8f647d8a896e9b8cea7a27b /src/libstd/sys
parenta2b469c4ccf3777294422c350c10012ca2e22e25 (diff)
parent61ef72fe4951148e3987af21ee76ace6745c8a62 (diff)
downloadrust-675bdf6d6d7b6441598961052df6466efbb4bee4.tar.gz
rust-675bdf6d6d7b6441598961052df6466efbb4bee4.zip
Rollup merge of #70207 - hatoo:macos-getentropy, r=dtolnay
Use getentropy(2) on macos

resolves #70179
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/unix/rand.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs
index 9ce5f3d014c..eed6fbf13b7 100644
--- a/src/libstd/sys/unix/rand.rs
+++ b/src/libstd/sys/unix/rand.rs
@@ -12,6 +12,7 @@ pub fn hashmap_random_keys() -> (u64, u64) {
 
 #[cfg(all(
     unix,
+    not(target_os = "macos"),
     not(target_os = "ios"),
     not(target_os = "openbsd"),
     not(target_os = "freebsd"),
@@ -92,6 +93,42 @@ mod imp {
     }
 }
 
+#[cfg(target_os = "macos")]
+mod imp {
+    use crate::fs::File;
+    use crate::io::Read;
+    use crate::sys::os::errno;
+    use libc::{c_int, c_void, size_t};
+
+    fn getentropy_fill_bytes(v: &mut [u8]) -> bool {
+        weak!(fn getentropy(*mut c_void, size_t) -> c_int);
+
+        getentropy
+            .get()
+            .map(|f| {
+                // getentropy(2) permits a maximum buffer size of 256 bytes
+                for s in v.chunks_mut(256) {
+                    let ret = unsafe { f(s.as_mut_ptr() as *mut c_void, s.len()) };
+                    if ret == -1 {
+                        panic!("unexpected getentropy error: {}", errno());
+                    }
+                }
+                true
+            })
+            .unwrap_or(false)
+    }
+
+    pub fn fill_bytes(v: &mut [u8]) {
+        if getentropy_fill_bytes(v) {
+            return;
+        }
+
+        // for older macos which doesn't support getentropy
+        let mut file = File::open("/dev/urandom").expect("failed to open /dev/urandom");
+        file.read_exact(v).expect("failed to read /dev/urandom")
+    }
+}
+
 #[cfg(target_os = "openbsd")]
 mod imp {
     use crate::sys::os::errno;