std::rand::os: use the externfn! macro for the Windows RNG.

This commit is contained in:
Huon Wilson 2013-10-09 09:45:38 +11:00
parent d86de18b61
commit 618c6afe32

View File

@ -21,6 +21,13 @@ use rt::io::{file, Open, Read};
#[cfg(windows)] #[cfg(windows)]
use cast; use cast;
#[cfg(windows)]
use libc::{c_long, DWORD, BYTE};
#[cfg(windows)]
type HCRYPTPROV = c_long;
// the extern functions imported from the runtime on Windows are
// implemented so that they either succeed or abort(), so we can just
// assume they work when we call them.
/// A random number generator that retrieves randomness straight from /// A random number generator that retrieves randomness straight from
/// the operating system. On Unix-like systems this reads from /// the operating system. On Unix-like systems this reads from
@ -38,7 +45,7 @@ pub struct OSRng {
/// This does not block. /// This does not block.
#[cfg(windows)] #[cfg(windows)]
pub struct OSRng { pub struct OSRng {
priv hcryptprov: raw::HCRYPTPROV priv hcryptprov: HCRYPTPROV
} }
impl OSRng { impl OSRng {
@ -53,10 +60,11 @@ impl OSRng {
/// Create a new `OSRng`. /// Create a new `OSRng`.
#[cfg(windows)] #[cfg(windows)]
#[fixed_stack_segment] #[inline(never)]
pub fn new() -> OSRng { pub fn new() -> OSRng {
externfn!(fn rust_win32_rand_acquire(phProv: *mut HCRYPTPROV))
let mut hcp = 0; let mut hcp = 0;
unsafe {raw::rust_win32_rand_acquire(&mut hcp)}; unsafe {rust_win32_rand_acquire(&mut hcp)};
OSRng { hcryptprov: hcp } OSRng { hcryptprov: hcp }
} }
@ -87,12 +95,11 @@ impl Rng for OSRng {
self.fill_bytes(v); self.fill_bytes(v);
unsafe { cast::transmute(v) } unsafe { cast::transmute(v) }
} }
#[fixed_stack_segment] #[inline(never)]
fn fill_bytes(&mut self, v: &mut [u8]) { fn fill_bytes(&mut self, v: &mut [u8]) {
use libc::DWORD; externfn!(fn rust_win32_rand_gen(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: *mut BYTE))
do v.as_mut_buf |ptr, len| { do v.as_mut_buf |ptr, len| {
unsafe {raw::rust_win32_rand_gen(self.hcryptprov, len as DWORD, ptr)} unsafe {rust_win32_rand_gen(self.hcryptprov, len as DWORD, ptr)}
} }
} }
} }
@ -105,26 +112,13 @@ impl Drop for OSRng {
} }
#[cfg(windows)] #[cfg(windows)]
#[fixed_stack_segment] #[inline(never)]
fn drop(&mut self) { fn drop(&mut self) {
unsafe {raw::rust_win32_rand_release(self.hcryptprov)} externfn!(fn rust_win32_rand_release(hProv: HCRYPTPROV))
unsafe {rust_win32_rand_release(self.hcryptprov)}
} }
} }
#[cfg(windows)]
mod raw {
use libc::{c_long, DWORD, BYTE};
pub type HCRYPTPROV = c_long;
// these functions are implemented so that they either succeed or
// abort(), so we can just assume they work when we call them.
extern {
pub fn rust_win32_rand_acquire(phProv: *mut HCRYPTPROV);
pub fn rust_win32_rand_gen(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: *mut BYTE);
pub fn rust_win32_rand_release(hProv: HCRYPTPROV);
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {