Skip to content

Commit b771a82

Browse files
committed
Revise error types and codes
1 parent 679c52c commit b771a82

19 files changed

+161
-54
lines changed

src/cloudabi.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,6 @@ pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
2222
Err(Error::from(code))
2323
}
2424
}
25+
26+
#[inline(always)]
27+
pub fn error_msg_inner(_: NonZeroU32) -> Option<&'static str> { None }

src/dragonfly_haiku.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
// except according to those terms.
88

99
//! Implementation for DragonFly / Haiku
10-
use super::Error;
11-
use super::utils::use_init;
10+
use error::Error;
11+
use utils::use_init;
1212
use std::fs::File;
1313
use std::io::Read;
1414
use std::cell::RefCell;
15+
use std::num::NonZeroU32;
1516

1617
thread_local!(static RNG_FILE: RefCell<Option<File>> = RefCell::new(None));
1718

@@ -23,3 +24,6 @@ pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
2324
)
2425
})
2526
}
27+
28+
#[inline(always)]
29+
pub fn error_msg_inner(_: NonZeroU32) -> Option<&'static str> { None }

src/dummy.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77
// except according to those terms.
88

99
//! A dummy implementation for unsupported targets which always returns
10-
//! `Err(UNAVAILABLE_ERROR)`
11-
use super::UNAVAILABLE_ERROR;
10+
//! `Err(error::UNAVAILABLE)`
11+
use std::num::NonZeroU32;
12+
use error::{Error, UNAVAILABLE};
1213

13-
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
14-
Err(UNAVAILABLE_ERROR)
14+
pub fn getrandom_inner(_: &mut [u8]) -> Result<(), Error> {
15+
Err(UNAVAILABLE)
1516
}
17+
18+
#[inline(always)]
19+
pub fn error_msg_inner(_: NonZeroU32) -> Option<&'static str> { None }

src/emscripten.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
// except according to those terms.
88

99
//! Implementation for Emscripten
10-
use super::Error;
10+
use error::Error;
1111
use std::fs::File;
1212
use std::io::Read;
1313
use std::cell::RefCell;
14-
use super::utils::use_init;
14+
use std::num::NonZeroU32;
15+
use utils::use_init;
1516

1617
thread_local!(static RNG_FILE: RefCell<Option<File>> = RefCell::new(None));
1718

@@ -29,3 +30,6 @@ pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
2930
})
3031
})
3132
}
33+
34+
#[inline(always)]
35+
pub fn error_msg_inner(_: NonZeroU32) -> Option<&'static str> { None }

src/error.rs

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,25 @@ use core::fmt;
1212
#[cfg(not(target_env = "sgx"))]
1313
use std::{io, error};
1414

15+
// A randomly-chosen 16-bit prefix for our codes
16+
pub(crate) const CODE_PREFIX: u32 = 0x57f40000;
17+
const CODE_UNKNOWN: u32 = CODE_PREFIX | 0;
18+
const CODE_UNAVAILABLE: u32 = CODE_PREFIX | 1;
19+
1520
/// An unknown error.
16-
pub const UNKNOWN_ERROR: Error = Error(unsafe {
17-
NonZeroU32::new_unchecked(0x756e6b6e) // "unkn"
21+
pub const UNKNOWN: Error = Error(unsafe {
22+
NonZeroU32::new_unchecked(CODE_UNKNOWN)
1823
});
1924

2025
/// No generator is available.
21-
pub const UNAVAILABLE_ERROR: Error = Error(unsafe {
22-
NonZeroU32::new_unchecked(0x4e416e61) // "NAna"
26+
pub const UNAVAILABLE: Error = Error(unsafe {
27+
NonZeroU32::new_unchecked(CODE_UNAVAILABLE)
2328
});
2429

2530
/// The error type.
2631
///
2732
/// This type is small and no-std compatible.
28-
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
33+
#[derive(Copy, Clone, Eq, PartialEq)]
2934
pub struct Error(NonZeroU32);
3035

3136
impl Error {
@@ -38,14 +43,34 @@ impl Error {
3843
pub fn code(&self) -> NonZeroU32 {
3944
self.0
4045
}
46+
47+
fn msg(&self) -> Option<&'static str> {
48+
if let Some(msg) = super::error_msg_inner(self.0) {
49+
Some(msg)
50+
} else {
51+
match *self {
52+
UNKNOWN => Some("getrandom: unknown error"),
53+
UNAVAILABLE => Some("getrandom: unavailable"),
54+
_ => None
55+
}
56+
}
57+
}
58+
}
59+
60+
impl fmt::Debug for Error {
61+
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
62+
match self.msg() {
63+
Some(msg) => write!(f, "Error(\"{}\")", msg),
64+
None => write!(f, "Error({})", self.0.get()),
65+
}
66+
}
4167
}
4268

4369
impl fmt::Display for Error {
4470
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
45-
match *self {
46-
UNKNOWN_ERROR => write!(f, "Getrandom Error: unknown"),
47-
UNAVAILABLE_ERROR => write!(f, "Getrandom Error: unavailable"),
48-
code => write!(f, "Getrandom Error: {}", code.0.get()),
71+
match self.msg() {
72+
Some(msg) => write!(f, "{}", msg),
73+
None => write!(f, "getrandom: unknown code {}", self.0.get()),
4974
}
5075
}
5176
}
@@ -63,22 +88,31 @@ impl From<io::Error> for Error {
6388
.and_then(|code| NonZeroU32::new(code as u32))
6489
.map(|code| Error(code))
6590
// in practice this should never happen
66-
.unwrap_or(UNKNOWN_ERROR)
91+
.unwrap_or(UNKNOWN)
6792
}
6893
}
6994

7095
#[cfg(not(target_env = "sgx"))]
7196
impl From<Error> for io::Error {
7297
fn from(err: Error) -> Self {
73-
match err {
74-
UNKNOWN_ERROR => io::Error::new(io::ErrorKind::Other,
75-
"getrandom error: unknown"),
76-
UNAVAILABLE_ERROR => io::Error::new(io::ErrorKind::Other,
77-
"getrandom error: entropy source is unavailable"),
78-
code => io::Error::from_raw_os_error(code.0.get() as i32),
98+
match err.msg() {
99+
Some(msg) => io::Error::new(io::ErrorKind::Other, msg),
100+
None => io::Error::from_raw_os_error(err.0.get() as i32),
79101
}
80102
}
81103
}
82104

83105
#[cfg(not(target_env = "sgx"))]
84106
impl error::Error for Error { }
107+
108+
#[cfg(test)]
109+
mod tests {
110+
use std::mem::size_of;
111+
use super::Error;
112+
113+
#[test]
114+
fn test_size() {
115+
assert_eq!(size_of::<Error>(), 4);
116+
assert_eq!(size_of::<Result<(), Error>>(), 4);
117+
}
118+
}

src/freebsd.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
//! Implementation for FreeBSD
1010
extern crate libc;
1111

12-
use super::Error;
12+
use error::Error;
1313
use core::ptr;
1414
use std::io;
15+
use std::num::NonZeroU32;
1516

1617
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
1718
let mib = [libc::CTL_KERN, libc::KERN_ARND];
@@ -30,3 +31,6 @@ pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
3031
}
3132
Ok(())
3233
}
34+
35+
#[inline(always)]
36+
pub fn error_msg_inner(_: NonZeroU32) -> Option<&'static str> { None }

src/fuchsia.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@
99
//! Implementation for Fuchsia Zircon
1010
extern crate fuchsia_cprng;
1111

12-
use super::Error;
12+
use std::num::NonZeroU32;
13+
use error::Error;
1314

1415
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
1516
fuchsia_cprng::cprng_draw(dest);
1617
Ok(())
1718
}
19+
20+
#[inline(always)]
21+
pub fn error_msg_inner(_: NonZeroU32) -> Option<&'static str> { None }

src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,7 @@ extern crate wasm_bindgen;
123123
target_arch = "wasm32",
124124
))]
125125
mod utils;
126-
mod error;
127-
pub use error::{Error, UNKNOWN_ERROR, UNAVAILABLE_ERROR};
126+
pub mod error;
128127

129128

130129
// System-specific implementations.
@@ -136,7 +135,7 @@ macro_rules! mod_use {
136135
#[$cond]
137136
mod $module;
138137
#[$cond]
139-
use $module::getrandom_inner;
138+
use $module::{getrandom_inner, error_msg_inner};
140139
}
141140
}
142141

@@ -221,7 +220,7 @@ mod_use!(
221220
/// In general, `getrandom` will be fast enough for interactive usage, though
222221
/// significantly slower than a user-space CSPRNG; for the latter consider
223222
/// [`rand::thread_rng`](https://docs.rs/rand/*/rand/fn.thread_rng.html).
224-
pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
223+
pub fn getrandom(dest: &mut [u8]) -> Result<(), error::Error> {
225224
getrandom_inner(dest)
226225
}
227226

src/linux_android.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
//! Implementation for Linux / Android
1010
extern crate libc;
1111

12-
use super::Error;
13-
use super::utils::use_init;
12+
use error::Error;
13+
use utils::use_init;
1414
use std::fs::File;
1515
use std::io;
1616
use std::io::Read;
1717
use std::cell::RefCell;
18+
use std::num::NonZeroU32;
1819
use std::sync::atomic::{AtomicBool, Ordering};
1920

2021
static RNG_INIT: AtomicBool = AtomicBool::new(false);
@@ -80,3 +81,6 @@ fn is_getrandom_available() -> bool {
8081

8182
AVAILABLE.load(Ordering::Relaxed)
8283
}
84+
85+
#[inline(always)]
86+
pub fn error_msg_inner(_: NonZeroU32) -> Option<&'static str> { None }

src/macos.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
//! Implementation for MacOS / iOS
1010
extern crate libc;
1111

12-
use super::Error;
12+
use error::Error;
1313
use std::io;
14+
use std::num::NonZeroU32;
1415
use self::libc::{c_int, size_t};
1516

1617
enum SecRandom {}
@@ -40,3 +41,6 @@ pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
4041
Ok(())
4142
}
4243
}
44+
45+
#[inline(always)]
46+
pub fn error_msg_inner(_: NonZeroU32) -> Option<&'static str> { None }

0 commit comments

Comments
 (0)