Skip to content

Commit afeaf6a

Browse files
committed
---
yaml --- r: 95282 b: refs/heads/dist-snap c: 29e3b33 h: refs/heads/master v: v3
1 parent adc05ed commit afeaf6a

File tree

9 files changed

+111
-153
lines changed

9 files changed

+111
-153
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: c274a6888410ce3e357e014568b43310ed787d36
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: fb9706338d56599ea3073b5f8e93c2e769431a48
9+
refs/heads/dist-snap: 29e3b33a0954f2494278d74344792f4b84a44120
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/mk/rt.mk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ RUNTIME_CXXS_$(1)_$(2) := \
8686
rt/sync/lock_and_signal.cpp \
8787
rt/sync/rust_thread.cpp \
8888
rt/rust_builtin.cpp \
89-
rt/rust_rng.cpp \
9089
rt/rust_upcall.cpp \
9190
rt/rust_uv.cpp \
9291
rt/miniz.cpp \

branches/dist-snap/src/libstd/rand/os.rs

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,8 @@ use rand::reader::ReaderRng;
1919
#[cfg(unix)]
2020
use rt::io::{file, Open, Read};
2121

22-
#[cfg(windows)]
23-
use ptr;
2422
#[cfg(windows)]
2523
use cast;
26-
#[cfg(windows)]
27-
use libc::{GetLastError, FALSE};
2824

2925
/// A random number generator that retrieves randomness straight from
3026
/// the operating system. On Unix-like systems this reads from
@@ -40,9 +36,6 @@ pub struct OSRng {
4036
/// `/dev/urandom`, on Windows this uses `CryptGenRandom`.
4137
///
4238
/// This does not block.
43-
///
44-
/// XXX: it is unlikely that this is threadsafe with the use of
45-
/// GetLastError.
4639
#[cfg(windows)]
4740
pub struct OSRng {
4841
priv hcryptprov: raw::HCRYPTPROV
@@ -60,12 +53,10 @@ impl OSRng {
6053

6154
/// Create a new `OSRng`.
6255
#[cfg(windows)]
56+
#[fixed_stack_segment] #[inline(never)]
6357
pub fn new() -> OSRng {
64-
let hcp = ptr::mut_null();
65-
// TODO these two 0 constants are incorrect!
66-
if unsafe { raw::CryptAcquireContext(hcp, ptr::null(), ptr::null(), 0, 0); } == FALSE {
67-
fail!("CryptAcquireContext failed with error %u", unsafe {GetLastError()})
68-
}
58+
let mut hcp = 0;
59+
unsafe {raw::rust_win32_rand_acquire(&mut hcp)};
6960

7061
OSRng { hcryptprov: hcp }
7162
}
@@ -96,9 +87,12 @@ impl Rng for OSRng {
9687
self.fill_bytes(v);
9788
unsafe { cast::transmute(v) }
9889
}
90+
#[fixed_stack_segment] #[inline(never)]
9991
fn fill_bytes(&mut self, v: &mut [u8]) {
100-
if unsafe { raw::CryptGenRandom(self.hcryptprov, v.len(), v.unsafe_mut_ref(0)) } == FALSE {
101-
fail!("CryptGenRandom failed with error %u", unsafe {GetLastError()})
92+
use libc::DWORD;
93+
94+
do v.as_mut_buf |ptr, len| {
95+
unsafe {raw::rust_win32_rand_gen(self.hcryptprov, len as DWORD, ptr)}
10296
}
10397
}
10498
}
@@ -111,27 +105,24 @@ impl Drop for OSRng {
111105
}
112106

113107
#[cfg(windows)]
108+
#[fixed_stack_segment] #[inline(never)]
114109
fn drop(&mut self) {
115-
// TODO this 0 means?
116-
if unsafe { raw::CryptReleaseContext(self.hcryptprov, 0)} == FALSE {
117-
fail!("CryptReleaseContext failed with error %u", unsafe {GetLastError()})
118-
}
110+
unsafe {raw::rust_win32_rand_release(self.hcryptprov)}
119111
}
120112
}
121113

122-
#[abi = "cdecl"]
123114
#[cfg(windows)]
124115
mod raw {
125-
use libc::{LPCTSTR, DWORD, BOOL, BYTE};
116+
use libc::{c_long, DWORD, BYTE};
117+
118+
pub type HCRYPTPROV = c_long;
126119

127-
enum HCRYPTPROV_opaque {}
128-
pub type HCRYPTPROV = *CRYPTPROV;
120+
// these functions are implemented so that they either succeed or
121+
// abort(), so we can just assume they work when we call them.
129122
extern {
130-
pub fn CryptAcquireContext(phProv: *mut HCRYPTPROV,
131-
pszContainer: LPCTSTR, pszProvider: LPCTSTR,
132-
dwProvType: DWORD, dwFlags: DWORD) -> BOOL;
133-
pub fn CryptGenRandom(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: *mut BYTE) -> BOOL;
134-
pub fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
123+
pub fn rust_win32_rand_acquire(phProv: *mut HCRYPTPROV);
124+
pub fn rust_win32_rand_gen(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: *mut BYTE);
125+
pub fn rust_win32_rand_release(hProv: HCRYPTPROV);
135126
}
136127
}
137128

branches/dist-snap/src/libstd/rand/reader.rs

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,28 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use option::{Some, None};
1112
use rt::io::Reader;
1213
use rt::io::ReaderByteConversions;
1314

1415
use rand::Rng;
1516

1617
/// An RNG that reads random bytes straight from a `Reader`. This will
17-
/// work best with an infinite reader, but this is not required. The
18-
/// semantics of reading past the end of the reader are the same as
19-
/// those of the `read` method of the inner `Reader`.
18+
/// work best with an infinite reader, but this is not required.
19+
///
20+
/// It will fail if it there is insufficient data to fulfill a request.
21+
///
22+
/// # Example
23+
///
24+
/// ```rust
25+
/// use std::rand::reader;
26+
/// use std::rt::io::mem;
27+
///
28+
/// fn main() {
29+
/// let mut rng = reader::ReaderRng::new(mem::MemReader::new(~[1,2,3,4,5,6,7,8]));
30+
/// println!("{}", rng.gen::<uint>());
31+
/// }
32+
/// ```
2033
pub struct ReaderRng<R> {
2134
priv reader: R
2235
}
@@ -32,8 +45,6 @@ impl<R: Reader> ReaderRng<R> {
3245

3346
impl<R: Reader> Rng for ReaderRng<R> {
3447
fn next_u32(&mut self) -> u32 {
35-
// XXX which is better: consistency between big/little-endian
36-
// platforms, or speed.
3748
if cfg!(target_endian="little") {
3849
self.reader.read_le_u32_()
3950
} else {
@@ -48,8 +59,13 @@ impl<R: Reader> Rng for ReaderRng<R> {
4859
}
4960
}
5061
fn fill_bytes(&mut self, v: &mut [u8]) {
51-
// XXX: check that we filled `v``
52-
let _n = self.reader.read(v);
62+
if v.len() == 0 { return }
63+
match self.reader.read(v) {
64+
Some(n) if n == v.len() => return,
65+
Some(n) => fail2!("ReaderRng.fill_bytes could not fill buffer: \
66+
read {} out of {} bytes.", n, v.len()),
67+
None => fail2!("ReaderRng.fill_bytes reached eof.")
68+
}
5369
}
5470
}
5571

@@ -91,4 +107,12 @@ mod test {
91107

92108
assert_eq!(v, w);
93109
}
110+
111+
#[test]
112+
#[should_fail]
113+
fn test_reader_rng_insufficient_bytes() {
114+
let mut rng = ReaderRng::new(MemReader::new(~[]));
115+
let mut v = [0u8, .. 3];
116+
rng.fill_bytes(v);
117+
}
94118
}

branches/dist-snap/src/libstd/rt/sched.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use rt::local::Local;
2626
use rt::rtio::{RemoteCallback, PausibleIdleCallback};
2727
use borrow::{to_uint};
2828
use cell::Cell;
29-
use rand::{SeedableRng, XorShiftRng, Rng, Rand};
29+
use rand::{XorShiftRng, Rng, Rand};
3030
use iter::range;
3131
use vec::{OwnedVector};
3232

@@ -862,6 +862,7 @@ fn new_sched_rng() -> XorShiftRng {
862862
use ptr::RawPtr;
863863
use vec::MutableVector;
864864
use iter::Iterator;
865+
use rand::SeedableRng;
865866

866867
// XXX: this could use io::native::file, when it works.
867868
let file = do "/dev/urandom".with_c_str |name| {

branches/dist-snap/src/rt/rust_builtin.cpp

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include "sync/lock_and_signal.h"
1616
#include "memory_region.h"
1717
#include "boxed_region.h"
18-
#include "rust_rng.h"
1918
#include "vg/valgrind.h"
2019
#include "sp.h"
2120

@@ -69,11 +68,6 @@ rust_env_pairs() {
6968
}
7069
#endif
7170

72-
extern "C" CDECL void
73-
rand_gen_seed(uint8_t* dest, size_t size) {
74-
rng_gen_seed(dest, size);
75-
}
76-
7771
extern "C" CDECL char*
7872
#if defined(__WIN32__)
7973
rust_list_dir_val(WIN32_FIND_DATA* entry_ptr) {
@@ -654,6 +648,62 @@ rust_unset_sigprocmask() {
654648

655649
#endif
656650

651+
#if defined(__WIN32__)
652+
void
653+
win32_require(LPCTSTR fn, BOOL ok) {
654+
if (!ok) {
655+
LPTSTR buf;
656+
DWORD err = GetLastError();
657+
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
658+
FORMAT_MESSAGE_FROM_SYSTEM |
659+
FORMAT_MESSAGE_IGNORE_INSERTS,
660+
NULL, err,
661+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
662+
(LPTSTR) &buf, 0, NULL );
663+
fprintf(stderr, "%s failed with error %ld: %s", fn, err, buf);
664+
LocalFree((HLOCAL)buf);
665+
abort();
666+
}
667+
}
668+
669+
extern "C" CDECL void
670+
rust_win32_rand_acquire(HCRYPTPROV* phProv) {
671+
win32_require
672+
(_T("CryptAcquireContext"),
673+
CryptAcquireContext(phProv, NULL, NULL, PROV_RSA_FULL,
674+
CRYPT_VERIFYCONTEXT|CRYPT_SILENT));
675+
676+
}
677+
extern "C" CDECL void
678+
rust_win32_rand_gen(HCRYPTPROV hProv, DWORD dwLen, BYTE* pbBuffer) {
679+
win32_require
680+
(_T("CryptGenRandom"), CryptGenRandom(hProv, dwLen, pbBuffer));
681+
}
682+
extern "C" CDECL void
683+
rust_win32_rand_release(HCRYPTPROV hProv) {
684+
win32_require
685+
(_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0));
686+
}
687+
688+
#else
689+
690+
// these symbols are listed in rustrt.def.in, so they need to exist; but they
691+
// should never be called.
692+
693+
extern "C" CDECL void
694+
rust_win32_rand_acquire() {
695+
abort();
696+
}
697+
extern "C" CDECL void
698+
rust_win32_rand_gen() {
699+
abort();
700+
}
701+
extern "C" CDECL void
702+
rust_win32_rand_release() {
703+
abort();
704+
}
705+
706+
#endif
657707
//
658708
// Local Variables:
659709
// mode: C++

branches/dist-snap/src/rt/rust_rng.cpp

Lines changed: 0 additions & 83 deletions
This file was deleted.

branches/dist-snap/src/rt/rust_rng.h

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)