@@ -3,8 +3,8 @@ use super::use_file;
3
3
use crate :: Error ;
4
4
use core:: {
5
5
ffi:: c_void,
6
- mem:: { self , MaybeUninit } ,
7
- ptr:: { self , NonNull } ,
6
+ mem:: { transmute , MaybeUninit } ,
7
+ ptr:: NonNull ,
8
8
sync:: atomic:: { AtomicPtr , Ordering } ,
9
9
} ;
10
10
use use_file:: util_libc;
@@ -17,18 +17,28 @@ type GetRandomFn = unsafe extern "C" fn(*mut c_void, libc::size_t, libc::c_uint)
17
17
/// or not supported by kernel.
18
18
const NOT_AVAILABLE : NonNull < c_void > = unsafe { NonNull :: new_unchecked ( usize:: MAX as * mut c_void ) } ;
19
19
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 ( ) ) ;
21
21
22
22
#[ cold]
23
23
#[ inline( never) ]
24
24
fn 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
+
28
38
let res_ptr = match NonNull :: new ( raw_ptr) {
29
39
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 ( ) ;
32
42
// Check that `getrandom` syscall is supported by kernel
33
43
let res = unsafe { getrandom_fn ( dangling_ptr, 0 , 0 ) } ;
34
44
if cfg ! ( getrandom_test_linux_fallback) {
@@ -54,7 +64,7 @@ fn init() -> NonNull<c_void> {
54
64
res_ptr
55
65
}
56
66
57
- // prevent inlining of the fallback implementation
67
+ // Prevent inlining of the fallback implementation
58
68
#[ inline( never) ]
59
69
fn use_file_fallback ( dest : & mut [ MaybeUninit < u8 > ] ) -> Result < ( ) , Error > {
60
70
use_file:: fill_inner ( dest)
@@ -78,7 +88,7 @@ pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
78
88
use_file_fallback ( dest)
79
89
} else {
80
90
// 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) } ;
82
92
util_libc:: sys_fill_exact ( dest, |buf| unsafe {
83
93
getrandom_fn ( buf. as_mut_ptr ( ) . cast ( ) , buf. len ( ) , 0 )
84
94
} )
0 commit comments