@@ -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