11#[ cfg( feature = "std" ) ]  
22extern  crate  std; 
33
4- use  core:: { fmt,  num :: NonZeroU32 } ; 
4+ use  core:: fmt; 
55
66// This private alias mirrors `std::io::RawOsError`: 
77// https://doc.rust-lang.org/std/io/type.RawOsError.html) 
88cfg_if:: cfg_if!( 
99    if  #[ cfg( target_os = "uefi" ) ]  { 
1010        type  RawOsError  = usize ; 
11+         type  NonZeroRawOsError  = core:: num:: NonZeroUsize ; 
12+         const  UEFI_ERROR_FLAG :  RawOsError  = 1  << ( RawOsError :: BITS  - 1 ) ; 
1113    }  else { 
1214        type  RawOsError  = i32 ; 
15+         type  NonZeroRawOsError  = core:: num:: NonZeroI32 ; 
1316    } 
1417) ; 
1518
@@ -27,8 +30,10 @@ cfg_if::cfg_if!(
2730///   [`std::error::Error`](https://doc.rust-lang.org/std/error/trait.Error.html) 
2831/// - [`std::io::Error`](https://doc.rust-lang.org/std/io/struct.Error.html) implements 
2932///   [`From<getrandom::Error>`](https://doc.rust-lang.org/std/convert/trait.From.html). 
33+ // note: on non-UEFI targets OS errors are represented as negative integers, 
34+ // while on UEFI targets OS errors have the highest bit set to 1. 
3035#[ derive( Copy ,  Clone ,  Eq ,  PartialEq ) ]  
31- pub  struct  Error ( NonZeroU32 ) ; 
36+ pub  struct  Error ( NonZeroRawOsError ) ; 
3237
3338impl  Error  { 
3439    /// This target/platform is not supported by `getrandom`. 
@@ -38,28 +43,33 @@ impl Error {
3843    /// Encountered an unexpected situation which should not happen in practice. 
3944pub  const  UNEXPECTED :  Error  = Self :: new_internal ( 2 ) ; 
4045
41-     /// Codes below this point represent OS Errors (i.e. positive i32 values). 
42- /// Codes at or above this point, but below [`Error::CUSTOM_START`] are 
43- /// reserved for use by the `rand` and `getrandom` crates. 
46+     /// Deprecated. 
47+ #[ deprecated]  
4448    pub  const  INTERNAL_START :  u32  = 1  << 31 ; 
4549
46-     /// Codes at or above this point can be used by users to define their own  
47- /// custom errors. 
50+     /// Deprecated.  
51+ # [ deprecated ] 
4852    pub  const  CUSTOM_START :  u32  = ( 1  << 31 )  + ( 1  << 30 ) ; 
4953
54+     /// Internal errors can be in the range of 2^16..2^17 
55+ const  INTERNAL_START2 :  RawOsError  = 1  << 16 ; 
56+     /// Custom errors can be in the range of 2^17..(2^17 + 2^16) 
57+ const  CUSTOM_START2 :  RawOsError  = 1  << 17 ; 
58+ 
5059    /// Creates a new instance of an `Error` from a particular OS error code. 
5160/// 
5261/// This method is analogous to [`std::io::Error::from_raw_os_error()`][1], 
5362/// except that it works in `no_std` contexts and `code` will be 
54- /// replaced with `Error::UNEXPECTED` if it isn't in the range 
55- /// `1..Error::INTERNAL_START`. Thus, for the result `r`, 
56- /// `r == Self::UNEXPECTED || r.raw_os_error().unsigned_abs() == code`. 
63+ /// replaced with `Error::UNEXPECTED` in unexpected cases. 
5764/// 
5865/// [1]: https://doc.rust-lang.org/std/io/struct.Error.html#method.from_raw_os_error 
5966#[ allow( dead_code) ]  
60-     pub ( super )  fn  from_os_error ( code :  u32 )  -> Self  { 
61-         match  NonZeroU32 :: new ( code)  { 
62-             Some ( code)  if  code. get ( )  < Self :: INTERNAL_START  => Self ( code) , 
67+     pub ( super )  fn  from_os_error ( code :  RawOsError )  -> Self  { 
68+         match  NonZeroRawOsError :: new ( code)  { 
69+             #[ cfg( target_os = "uefi" ) ]  
70+             Some ( code)  if  code. get ( )  &  UEFI_ERROR_FLAG  != 0  => Self ( code) , 
71+             #[ cfg( not( target_os = "uefi" ) ) ]  
72+             Some ( code)  if  code. get ( )  < 0  => Self ( code) , 
6373            _ => Self :: UNEXPECTED , 
6474        } 
6575    } 
@@ -79,27 +89,38 @@ impl Error {
7989#[ inline]  
8090    pub  fn  raw_os_error ( self )  -> Option < RawOsError >  { 
8191        let  code = self . 0 . get ( ) ; 
82-         if  code >= Self :: INTERNAL_START  { 
83-             return  None ; 
92+         #[ cfg( target_os = "uefi" ) ]  
93+         { 
94+             if  code &  UEFI_ERROR_FLAG  != 0  { 
95+                 Some ( code) 
96+             }  else  { 
97+                 None 
98+             } 
99+         } 
100+ 
101+         #[ cfg( not( target_os = "uefi" ) ) ]  
102+         { 
103+             if  code >= 0  { 
104+                 return  None ; 
105+             } 
106+             #[ cfg( not( target_os = "solid_asp3" ) ) ]  
107+             let  code = code. checked_neg ( ) ?; 
108+             Some ( code) 
84109        } 
85-         let  errno = RawOsError :: try_from ( code) . ok ( ) ?; 
86-         #[ cfg( target_os = "solid_asp3" ) ]  
87-         let  errno = -errno; 
88-         Some ( errno) 
89110    } 
90111
91112    /// Creates a new instance of an `Error` from a particular custom error code. 
92113pub  const  fn  new_custom ( n :  u16 )  -> Error  { 
93-         // SAFETY: code > 0 as CUSTOM_START > 0 and adding n  won't overflow a u32 . 
94-         let  code = Error :: CUSTOM_START  + ( n as  u32 ) ; 
95-         Error ( unsafe  {  NonZeroU32 :: new_unchecked ( code)  } ) 
114+         // SAFETY: code > 0 as CUSTOM_START > 0 and adding `n`  won't overflow `RawOsError` . 
115+         let  code = Error :: CUSTOM_START2  + ( n as  RawOsError ) ; 
116+         Error ( unsafe  {  NonZeroRawOsError :: new_unchecked ( code)  } ) 
96117    } 
97118
98119    /// Creates a new instance of an `Error` from a particular internal error code. 
99120pub ( crate )  const  fn  new_internal ( n :  u16 )  -> Error  { 
100-         // SAFETY: code > 0 as INTERNAL_START > 0 and adding n  won't overflow a u32 . 
101-         let  code = Error :: INTERNAL_START  + ( n as  u32 ) ; 
102-         Error ( unsafe  {  NonZeroU32 :: new_unchecked ( code)  } ) 
121+         // SAFETY: code > 0 as INTERNAL_START > 0 and adding `n`  won't overflow `RawOsError` . 
122+         let  code = Error :: INTERNAL_START2  + ( n as  RawOsError ) ; 
123+         Error ( unsafe  {  NonZeroRawOsError :: new_unchecked ( code)  } ) 
103124    } 
104125
105126    fn  internal_desc ( & self )  -> Option < & ' static  str >  { 
0 commit comments