99//! Implementations that just need to read from a file
1010extern crate std;
1111
12+ use crate :: util_libc:: LazyFd ;
1213use crate :: Error ;
14+ use core:: mem:: ManuallyDrop ;
1315use core:: num:: NonZeroU32 ;
14- use lazy_static :: lazy_static ;
16+ use std :: os :: unix :: io :: { FromRawFd , IntoRawFd , RawFd } ;
1517use std:: { fs:: File , io:: Read } ;
1618
1719#[ cfg( target_os = "redox" ) ]
@@ -29,28 +31,31 @@ const FILE_PATH: &str = "/dev/urandom";
2931const FILE_PATH : & str = "/dev/random" ;
3032
3133pub fn getrandom_inner ( dest : & mut [ u8 ] ) -> Result < ( ) , Error > {
32- lazy_static ! {
33- static ref FILE : Result < File , Error > = init_file( ) ;
34- }
35- let mut f = FILE . as_ref ( ) ? ;
34+ static FD : LazyFd = LazyFd :: new ( ) ;
35+ let fd = FD . init ( init_file) . ok_or ( Error :: UNKNOWN ) ? ;
36+ let file = ManuallyDrop :: new ( unsafe { File :: from_raw_fd ( fd ) } ) ;
37+ let mut file_ref : & File = & file ;
3638
3739 if cfg ! ( target_os = "emscripten" ) {
3840 // `Crypto.getRandomValues` documents `dest` should be at most 65536 bytes.
3941 for chunk in dest. chunks_mut ( 65536 ) {
40- f . read_exact ( chunk) ?;
42+ file_ref . read_exact ( chunk) ?;
4143 }
4244 } else {
43- f . read_exact ( dest) ?;
45+ file_ref . read_exact ( dest) ?;
4446 }
4547 Ok ( ( ) )
4648}
4749
48- fn init_file ( ) -> Result < File , Error > {
50+ fn init_file ( ) -> Option < RawFd > {
4951 if FILE_PATH == "/dev/urandom" {
5052 // read one byte from "/dev/random" to ensure that OS RNG has initialized
51- File :: open ( "/dev/random" ) ?. read_exact ( & mut [ 0u8 ; 1 ] ) ?;
53+ File :: open ( "/dev/random" )
54+ . ok ( ) ?
55+ . read_exact ( & mut [ 0u8 ; 1 ] )
56+ . ok ( ) ?;
5257 }
53- Ok ( File :: open ( FILE_PATH ) ? )
58+ Some ( File :: open ( FILE_PATH ) . ok ( ) ? . into_raw_fd ( ) )
5459}
5560
5661#[ inline( always) ]
0 commit comments