diff options
| author | bors <bors@rust-lang.org> | 2020-07-28 00:51:53 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-07-28 00:51:53 +0000 |
| commit | ac48e62db85e6db4bbe026490381ab205f4a614d (patch) | |
| tree | 14f64e683e3f64dcbcfb8c2c7cb45ac7592e6e09 /src/libstd/sys/unix/rand.rs | |
| parent | 9be8ffcb0206fc1558069a7b4766090df7877659 (diff) | |
| parent | 2c31b45ae878b821975c4ebd94cc1e49f6073fd0 (diff) | |
| download | rust-ac48e62db85e6db4bbe026490381ab205f4a614d.tar.gz rust-ac48e62db85e6db4bbe026490381ab205f4a614d.zip | |
Auto merge of #73265 - mark-i-m:mv-std, r=Mark-Simulacrum,mark-i-m
mv std libs to library/ This is the first step in refactoring the directory layout of this repository, with further followup steps planned (but not done yet). Background: currently, all crates are under src/, without nested src directories and with the unconventional `lib*` prefixes (e.g., `src/libcore/lib.rs`). This directory structures is not idiomatic and makes the `src/` directory rather overwhelming. To improve contributor experience and make things a bit more approachable, we are reorganizing the repo a bit. In this PR, we move the standard libs (basically anything that is "runtime", as opposed to part of the compiler, build system, or one of the tools, etc). The new layout moves these libraries to a new `library/` directory in the root of the repo. Additionally, we remove the `lib*` prefixes and add nested `src/` directories. The other crates/tools in this repo are not touched. So in summary: ``` library/<crate>/src/*.rs src/<all the rest> // unchanged ``` where `<crate>` is: - core - alloc - std - test - proc_macro - panic_abort - panic_unwind - profiler_builtins - term - unwind - rtstartup - backtrace - rustc-std-workspace-* There was a lot of discussion about this and a few rounds of compiler team approvals, FCPs, MCPs, and nominations. The original MCP is https://github.com/rust-lang/compiler-team/issues/298. The final approval of the compiler team was given here: https://github.com/rust-lang/rust/pull/73265#issuecomment-659498446. The name `library` was chosen to complement a later move of the compiler crates to a `compiler/` directory. There was a lot of discussion around adding the nested `src/` directories. Note that this does increase the nesting depth (plausibly important for manual traversal of the tree, e.g., through GitHub's UI or `cd`), but this is deemed to be better as it fits the standard layout of Rust crates throughout most of the ecosystem, though there is some debate about how much this should apply to multi-crate projects. Overall, there seem to be more people in favor of nested `src/` than against. After this PR, there are no dependencies out of the `library/` directory except on the `build_helper` (or crates.io crates).
Diffstat (limited to 'src/libstd/sys/unix/rand.rs')
| -rw-r--r-- | src/libstd/sys/unix/rand.rs | 230 |
1 files changed, 0 insertions, 230 deletions
diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs deleted file mode 100644 index eed6fbf13b7..00000000000 --- a/src/libstd/sys/unix/rand.rs +++ /dev/null @@ -1,230 +0,0 @@ -use crate::mem; -use crate::slice; - -pub fn hashmap_random_keys() -> (u64, u64) { - let mut v = (0, 0); - unsafe { - let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8, mem::size_of_val(&v)); - imp::fill_bytes(view); - } - v -} - -#[cfg(all( - unix, - not(target_os = "macos"), - not(target_os = "ios"), - not(target_os = "openbsd"), - not(target_os = "freebsd"), - not(target_os = "netbsd"), - not(target_os = "fuchsia"), - not(target_os = "redox") -))] -mod imp { - use crate::fs::File; - use crate::io::Read; - - #[cfg(any(target_os = "linux", target_os = "android"))] - fn getrandom(buf: &mut [u8]) -> libc::c_long { - unsafe { - libc::syscall(libc::SYS_getrandom, buf.as_mut_ptr(), buf.len(), libc::GRND_NONBLOCK) - } - } - - #[cfg(not(any(target_os = "linux", target_os = "android")))] - fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool { - false - } - - #[cfg(any(target_os = "linux", target_os = "android"))] - fn getrandom_fill_bytes(v: &mut [u8]) -> bool { - use crate::sync::atomic::{AtomicBool, Ordering}; - use crate::sys::os::errno; - - static GETRANDOM_UNAVAILABLE: AtomicBool = AtomicBool::new(false); - if GETRANDOM_UNAVAILABLE.load(Ordering::Relaxed) { - return false; - } - - let mut read = 0; - while read < v.len() { - let result = getrandom(&mut v[read..]); - if result == -1 { - let err = errno() as libc::c_int; - if err == libc::EINTR { - continue; - } else if err == libc::ENOSYS || err == libc::EPERM { - // Fall back to reading /dev/urandom if `getrandom` is not - // supported on the current kernel. - // - // Also fall back in case it is disabled by something like - // seccomp or inside of virtual machines. - GETRANDOM_UNAVAILABLE.store(true, Ordering::Relaxed); - return false; - } else if err == libc::EAGAIN { - return false; - } else { - panic!("unexpected getrandom error: {}", err); - } - } else { - read += result as usize; - } - } - true - } - - pub fn fill_bytes(v: &mut [u8]) { - // getrandom_fill_bytes here can fail if getrandom() returns EAGAIN, - // meaning it would have blocked because the non-blocking pool (urandom) - // has not initialized in the kernel yet due to a lack of entropy. The - // fallback we do here is to avoid blocking applications which could - // depend on this call without ever knowing they do and don't have a - // work around. The PRNG of /dev/urandom will still be used but over a - // possibly predictable entropy pool. - if getrandom_fill_bytes(v) { - return; - } - - // getrandom failed because it is permanently or temporarily (because - // of missing entropy) unavailable. Open /dev/urandom, read from it, - // and close it again. - 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 = "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; - - pub fn fill_bytes(v: &mut [u8]) { - // getentropy(2) permits a maximum buffer size of 256 bytes - for s in v.chunks_mut(256) { - let ret = unsafe { libc::getentropy(s.as_mut_ptr() as *mut libc::c_void, s.len()) }; - if ret == -1 { - panic!("unexpected getentropy error: {}", errno()); - } - } - } -} - -// On iOS and MacOS `SecRandomCopyBytes` calls `CCRandomCopyBytes` with -// `kCCRandomDefault`. `CCRandomCopyBytes` manages a CSPRNG which is seeded -// from `/dev/random` and which runs on its own thread accessed via GCD. -// This seems needlessly heavyweight for the purposes of generating two u64s -// once per thread in `hashmap_random_keys`. Therefore `SecRandomCopyBytes` is -// only used on iOS where direct access to `/dev/urandom` is blocked by the -// sandbox. -#[cfg(target_os = "ios")] -mod imp { - use crate::io; - use crate::ptr; - use libc::{c_int, size_t}; - - enum SecRandom {} - - #[allow(non_upper_case_globals)] - const kSecRandomDefault: *const SecRandom = ptr::null(); - - extern "C" { - fn SecRandomCopyBytes(rnd: *const SecRandom, count: size_t, bytes: *mut u8) -> c_int; - } - - pub fn fill_bytes(v: &mut [u8]) { - let ret = unsafe { SecRandomCopyBytes(kSecRandomDefault, v.len(), v.as_mut_ptr()) }; - if ret == -1 { - panic!("couldn't generate random bytes: {}", io::Error::last_os_error()); - } - } -} - -#[cfg(any(target_os = "freebsd", target_os = "netbsd"))] -mod imp { - use crate::ptr; - - pub fn fill_bytes(v: &mut [u8]) { - let mib = [libc::CTL_KERN, libc::KERN_ARND]; - // kern.arandom permits a maximum buffer size of 256 bytes - for s in v.chunks_mut(256) { - let mut s_len = s.len(); - let ret = unsafe { - libc::sysctl( - mib.as_ptr(), - mib.len() as libc::c_uint, - s.as_mut_ptr() as *mut _, - &mut s_len, - ptr::null(), - 0, - ) - }; - if ret == -1 || s_len != s.len() { - panic!( - "kern.arandom sysctl failed! (returned {}, s.len() {}, oldlenp {})", - ret, - s.len(), - s_len - ); - } - } - } -} - -#[cfg(target_os = "fuchsia")] -mod imp { - #[link(name = "zircon")] - extern "C" { - fn zx_cprng_draw(buffer: *mut u8, len: usize); - } - - pub fn fill_bytes(v: &mut [u8]) { - unsafe { zx_cprng_draw(v.as_mut_ptr(), v.len()) } - } -} - -#[cfg(target_os = "redox")] -mod imp { - use crate::fs::File; - use crate::io::Read; - - pub fn fill_bytes(v: &mut [u8]) { - // Open rand:, read from it, and close it again. - let mut file = File::open("rand:").expect("failed to open rand:"); - file.read_exact(v).expect("failed to read rand:") - } -} |
