11use std:: ffi:: c_int;
22
3- // The values are defined in libc
3+ #[ cfg( target_os = "windows" ) ]
4+ unsafe extern "C" {
5+ safe fn _errno ( ) -> * mut i32 ;
6+ }
7+
48#[ derive( Debug , PartialEq , Eq ) ]
59pub enum Error {
610 EDOM = 33 ,
@@ -14,8 +18,8 @@ impl TryFrom<c_int> for Error {
1418
1519 fn try_from ( value : c_int ) -> std:: result:: Result < Self , Self :: Error > {
1620 match value {
17- 33 => Ok ( Error :: EDOM ) ,
18- 34 => Ok ( Error :: ERANGE ) ,
21+ x if x == Error :: EDOM as c_int => Ok ( Error :: EDOM ) ,
22+ x if x == Error :: ERANGE as c_int => Ok ( Error :: ERANGE ) ,
1923 _ => Err ( value) ,
2024 }
2125 }
@@ -24,54 +28,60 @@ impl TryFrom<c_int> for Error {
2428/// Set errno to the given value.
2529#[ inline]
2630pub ( crate ) fn set_errno ( value : i32 ) {
31+ #[ cfg( target_os = "linux" ) ]
2732 unsafe {
28- #[ cfg( target_os = "linux" ) ]
29- {
30- * libc:: __errno_location ( ) = value;
31- }
32- #[ cfg( target_os = "macos" ) ]
33- {
34- * libc:: __error ( ) = value;
35- }
36- #[ cfg( target_os = "windows" ) ]
37- {
38- unsafe extern "C" {
39- safe fn _errno ( ) -> * mut i32 ;
40- }
41- * _errno ( ) = value;
42- }
43- #[ cfg( all( unix, not( any( target_os = "linux" , target_os = "macos" ) ) ) ) ]
44- {
45- // FreeBSD, NetBSD, OpenBSD, etc. use __error()
46- * libc:: __error ( ) = value;
47- }
33+ * libc:: __errno_location ( ) = value;
34+ }
35+ #[ cfg( target_os = "android" ) ]
36+ unsafe {
37+ * libc:: __errno ( ) = value;
38+ }
39+ #[ cfg( target_os = "macos" ) ]
40+ unsafe {
41+ * libc:: __error ( ) = value;
42+ }
43+ #[ cfg( target_os = "windows" ) ]
44+ unsafe {
45+ * _errno ( ) = value;
46+ }
47+ #[ cfg( all( unix, not( any( target_os = "linux" , target_os = "android" , target_os = "macos" ) ) ) ) ]
48+ unsafe {
49+ // FreeBSD, NetBSD, OpenBSD, etc. use __error()
50+ * libc:: __error ( ) = value;
4851 }
52+ // WASM and other targets: no-op (no errno)
53+ #[ cfg( not( any( unix, windows) ) ) ]
54+ let _ = value;
4955}
5056
5157/// Get the current errno value.
5258#[ inline]
5359pub ( crate ) fn get_errno ( ) -> i32 {
60+ #[ cfg( target_os = "linux" ) ]
5461 unsafe {
55- #[ cfg( target_os = "linux" ) ]
56- {
57- * libc:: __errno_location ( )
58- }
59- #[ cfg( target_os = "macos" ) ]
60- {
61- * libc:: __error ( )
62- }
63- #[ cfg( target_os = "windows" ) ]
64- {
65- unsafe extern "C" {
66- safe fn _errno ( ) -> * mut i32 ;
67- }
68- * _errno ( )
69- }
70- #[ cfg( all( unix, not( any( target_os = "linux" , target_os = "macos" ) ) ) ) ]
71- {
72- // FreeBSD, NetBSD, OpenBSD, etc. use __error()
73- * libc:: __error ( )
74- }
62+ * libc:: __errno_location ( )
63+ }
64+ #[ cfg( target_os = "android" ) ]
65+ unsafe {
66+ * libc:: __errno ( )
67+ }
68+ #[ cfg( target_os = "macos" ) ]
69+ unsafe {
70+ * libc:: __error ( )
71+ }
72+ #[ cfg( target_os = "windows" ) ]
73+ unsafe {
74+ * _errno ( )
75+ }
76+ #[ cfg( all( unix, not( any( target_os = "linux" , target_os = "android" , target_os = "macos" ) ) ) ) ]
77+ unsafe {
78+ // FreeBSD, NetBSD, OpenBSD, etc. use __error()
79+ * libc:: __error ( )
80+ }
81+ // WASM and other targets: no errno
82+ #[ cfg( not( any( unix, windows) ) ) ]
83+ {
84+ 0
7585 }
7686}
7787
@@ -80,8 +90,8 @@ pub(crate) fn get_errno() -> i32 {
8090pub ( crate ) fn is_error ( x : f64 ) -> Result < f64 > {
8191 match get_errno ( ) {
8292 0 => Ok ( x) ,
83- libc :: EDOM => Err ( Error :: EDOM ) ,
84- libc :: ERANGE => {
93+ e if e == Error :: EDOM as i32 => Err ( Error :: EDOM ) ,
94+ e if e == Error :: ERANGE as i32 => {
8595 // Underflow to zero is not an error.
8696 // Use 1.5 threshold to handle subnormal results that don't underflow to zero
8797 // (e.g., on Ubuntu/ia64) and to correctly detect underflows in expm1()
0 commit comments