@@ -3,8 +3,8 @@ use super::use_file;
33use  crate :: Error ; 
44use  core:: { 
55    ffi:: c_void, 
6-     mem:: { self ,  MaybeUninit } , 
7-     ptr:: { self ,   NonNull } , 
6+     mem:: { transmute ,  MaybeUninit } , 
7+     ptr:: NonNull , 
88    sync:: atomic:: { AtomicPtr ,  Ordering } , 
99} ; 
1010use  use_file:: util_libc; 
@@ -17,18 +17,28 @@ type GetRandomFn = unsafe extern "C" fn(*mut c_void, libc::size_t, libc::c_uint)
1717/// or not supported by kernel. 
1818const  NOT_AVAILABLE :  NonNull < c_void >  = unsafe  {  NonNull :: new_unchecked ( usize:: MAX  as  * mut  c_void )  } ; 
1919
20- static  GETRANDOM_FN :  AtomicPtr < c_void >  = AtomicPtr :: new ( ptr:: null_mut ( ) ) ; 
20+ static  GETRANDOM_FN :  AtomicPtr < c_void >  = AtomicPtr :: new ( core :: ptr:: null_mut ( ) ) ; 
2121
2222#[ cold]  
2323#[ inline( never) ]  
2424fn  init ( )  -> NonNull < c_void >  { 
25-     static  NAME :  & [ u8 ]  = b"getrandom\0 " ; 
26-     let  name_ptr = NAME . as_ptr ( ) . cast :: < libc:: c_char > ( ) ; 
27-     let  raw_ptr = unsafe  {  libc:: dlsym ( libc:: RTLD_DEFAULT ,  name_ptr)  } ; 
25+     // Use static linking to `libc::getrandom` on MUSL targets and `dlsym` everywhere else 
26+     #[ cfg( not( target_env = "musl" ) ) ]  
27+     let  raw_ptr = { 
28+         static  NAME :  & [ u8 ]  = b"getrandom\0 " ; 
29+         let  name_ptr = NAME . as_ptr ( ) . cast :: < libc:: c_char > ( ) ; 
30+         unsafe  {  libc:: dlsym ( libc:: RTLD_DEFAULT ,  name_ptr)  } 
31+     } ; 
32+     #[ cfg( target_env = "musl" ) ]  
33+     let  raw_ptr = { 
34+         let  fptr:  GetRandomFn  = libc:: getrandom; 
35+         unsafe  {  transmute :: < GetRandomFn ,  * mut  c_void > ( fptr)  } 
36+     } ; 
37+ 
2838    let  res_ptr = match  NonNull :: new ( raw_ptr)  { 
2939        Some ( fptr)  => { 
30-             let  getrandom_fn = unsafe  {  mem :: transmute :: < NonNull < c_void > ,  GetRandomFn > ( fptr)  } ; 
31-             let  dangling_ptr = ptr :: NonNull :: dangling ( ) . as_ptr ( ) ; 
40+             let  getrandom_fn = unsafe  {  transmute :: < NonNull < c_void > ,  GetRandomFn > ( fptr)  } ; 
41+             let  dangling_ptr = NonNull :: dangling ( ) . as_ptr ( ) ; 
3242            // Check that `getrandom` syscall is supported by kernel 
3343            let  res = unsafe  {  getrandom_fn ( dangling_ptr,  0 ,  0 )  } ; 
3444            if  cfg ! ( getrandom_test_linux_fallback)  { 
@@ -54,7 +64,7 @@ fn init() -> NonNull<c_void> {
5464    res_ptr
5565} 
5666
57- // prevent  inlining of the fallback implementation 
67+ // Prevent  inlining of the fallback implementation 
5868#[ inline( never) ]  
5969fn  use_file_fallback ( dest :  & mut  [ MaybeUninit < u8 > ] )  -> Result < ( ) ,  Error >  { 
6070    use_file:: fill_inner ( dest) 
@@ -78,7 +88,7 @@ pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
7888        use_file_fallback ( dest) 
7989    }  else  { 
8090        // note: `transmute` is currently the only way to convert a pointer into a function reference 
81-         let  getrandom_fn = unsafe  {  mem :: transmute :: < NonNull < c_void > ,  GetRandomFn > ( fptr)  } ; 
91+         let  getrandom_fn = unsafe  {  transmute :: < NonNull < c_void > ,  GetRandomFn > ( fptr)  } ; 
8292        util_libc:: sys_fill_exact ( dest,  |buf| unsafe  { 
8393            getrandom_fn ( buf. as_mut_ptr ( ) . cast ( ) ,  buf. len ( ) ,  0 ) 
8494        } ) 
0 commit comments