@@ -24,7 +24,10 @@ fn next_u64(mut fill_buf: &mut FnMut(&mut [u8])) -> u64 {
2424 unsafe { mem:: transmute :: < [ u8 ; 8 ] , u64 > ( buf) }
2525}
2626
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" ) ) ) ]
2831mod imp {
2932 use self :: OsRngInner :: * ;
3033 use super :: { next_u32, next_u64} ;
@@ -282,3 +285,51 @@ mod imp {
282285 }
283286 }
284287}
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