@@ -24,7 +24,10 @@ fn next_u64(mut fill_buf: &mut FnMut(&mut [u8])) -> u64 {
24
24
unsafe { mem:: transmute :: < [ u8 ; 8 ] , u64 > ( buf) }
25
25
}
26
26
27
- #[ cfg( all( unix, not( target_os = "ios" ) , not( target_os = "openbsd" ) ) ) ]
27
+ #[ cfg( all( unix,
28
+ not( target_os = "ios" ) ,
29
+ not( target_os = "openbsd" ) ,
30
+ not( target_os = "freebsd" ) ) ) ]
28
31
mod imp {
29
32
use self :: OsRngInner :: * ;
30
33
use super :: { next_u32, next_u64} ;
@@ -282,3 +285,51 @@ mod imp {
282
285
}
283
286
}
284
287
}
288
+
289
+ #[ cfg( target_os = "freebsd" ) ]
290
+ mod imp {
291
+ use super :: { next_u32, next_u64} ;
292
+
293
+ use io;
294
+ use libc;
295
+ use rand:: Rng ;
296
+ use ptr;
297
+
298
+ pub struct OsRng {
299
+ // dummy field to ensure that this struct cannot be constructed outside
300
+ // of this module
301
+ _dummy : ( ) ,
302
+ }
303
+
304
+ impl OsRng {
305
+ /// Create a new `OsRng`.
306
+ pub fn new ( ) -> io:: Result < OsRng > {
307
+ Ok ( OsRng { _dummy : ( ) } )
308
+ }
309
+ }
310
+
311
+ impl Rng for OsRng {
312
+ fn next_u32 ( & mut self ) -> u32 {
313
+ next_u32 ( & mut |v| self . fill_bytes ( v) )
314
+ }
315
+ fn next_u64 ( & mut self ) -> u64 {
316
+ next_u64 ( & mut |v| self . fill_bytes ( v) )
317
+ }
318
+ fn fill_bytes ( & mut self , v : & mut [ u8 ] ) {
319
+ let mib = [ libc:: CTL_KERN , libc:: KERN_ARND ] ;
320
+ // kern.arandom permits a maximum buffer size of 256 bytes
321
+ for s in v. chunks_mut ( 256 ) {
322
+ let mut s_len = s. len ( ) ;
323
+ let ret = unsafe {
324
+ libc:: sysctl ( mib. as_ptr ( ) , mib. len ( ) as libc:: c_uint ,
325
+ s. as_mut_ptr ( ) as * mut _ , & mut s_len,
326
+ ptr:: null ( ) , 0 )
327
+ } ;
328
+ if ret == -1 || s_len != s. len ( ) {
329
+ panic ! ( "kern.arandom sysctl failed! (returned {}, s.len() {}, oldlenp {})" ,
330
+ ret, s. len( ) , s_len) ;
331
+ }
332
+ }
333
+ }
334
+ }
335
+ }
0 commit comments