Skip to content

Commit 1e2a5aa

Browse files
committed
new error
1 parent f860bde commit 1e2a5aa

17 files changed

+106
-51
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ fuchsia-cprng = "0.1"
2121
[target.wasm32-unknown-unknown.dependencies]
2222
wasm-bindgen = { version = "0.2.12", optional = true }
2323
stdweb = { version = "0.4", optional = true }
24+
25+
[features]
26+
# Forces syscall usage on Linux, Android and Solaris
27+
force_syscall = []

src/cloudabi.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
1616
if errno == 0 {
1717
Ok(())
1818
} else {
19-
Err(Error::Unknown)
19+
Err(Error(unsafe {
20+
NonZeroU32::new_unchecked(errno as u32)
21+
}))
2022
}
2123
}

src/dragonfly_haiku.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ thread_local!(static RNG_FILE: RefCell<Option<File>> = RefCell::new(None));
1717

1818
pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
1919
RNG_FILE.with(|f| {
20-
use_init(f, || File::open("/dev/random"), |f| f.read_exact(dest))
21-
}).map_err(|_| Error::Unknown)
20+
use_init(f,
21+
|| File::open("/dev/random").map_err(From::from),
22+
|f| f.read_exact(dest).map_err(From::from),
23+
)
24+
})
2225
}

src/dummy.rs

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

99
//! A dummy implementation for unsupported targets which always returns
10-
//! `Err(Error::Unavailable)`
11-
use super::Error;
10+
//! `Err(UNAVAILABLE_ERROR)`
11+
use super::UNAVAILABLE_ERROR;
1212

1313
pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
14-
Err(Error::Unavailable)
14+
Err(UNAVAILABLE_ERROR)
1515
}

src/emscripten.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
2121
// task length variation, partition large randomBytes requests when
2222
// doing so as part of fulfilling a client request.
2323
RNG_FILE.with(|f| {
24-
use_init(f, || File::open("/dev/random"), |f| {
24+
use_init(f, || File::open("/dev/random").map_err(From::from), |f| {
2525
for chunk in dest.chunks_mut(65536) {
2626
f.read_exact(chunk)?;
2727
}
2828
Ok(())
2929
})
30-
}).map_err(|_| Error::Unknown)
30+
})
3131
}

src/error.rs

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,64 @@
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
88

9+
use core::num::NonZeroU32;
10+
use core::convert::From;
11+
use core::fmt;
12+
#[cfg(not(target_env = "sgx"))]
13+
use std::{io, error};
14+
15+
pub const UNKNOWN_ERROR: Error = Error(unsafe {
16+
NonZeroU32::new_unchecked(0x756e6b6e) // "unkn"
17+
});
18+
19+
pub const UNAVAILABLE_ERROR: Error = Error(unsafe {
20+
NonZeroU32::new_unchecked(0x4e416e61) // "NAna"
21+
});
22+
923
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
10-
pub enum Error {
11-
/// Call was interrupted.
12-
///
13-
/// Typically it can be retried.
14-
Interrupted,
15-
/// RNG source is unavailable on a given system.
16-
Unavailable,
17-
/// Unknown error.
18-
Unknown,
19-
#[doc(hidden)]
20-
__Nonexhaustive,
24+
pub struct Error(NonZeroU32);
25+
26+
impl Error {
27+
pub fn code(&self) -> NonZeroU32 {
28+
self.0
29+
}
30+
}
31+
32+
impl fmt::Display for Error {
33+
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
34+
match *self {
35+
UNKNOWN_ERROR => write!(f, "Getrandom Error: unknown"),
36+
UNAVAILABLE_ERROR => write!(f, "Getrandom Error: unavailable"),
37+
code => write!(f, "Getrandom Error: {}", code.0.get()),
38+
}
39+
}
2140
}
41+
42+
#[cfg(not(target_env = "sgx"))]
43+
impl From<io::Error> for Error {
44+
fn from(err: io::Error) -> Self {
45+
err.raw_os_error()
46+
.map(|code| Error(unsafe {
47+
// all supported targets use 0 as success code
48+
NonZeroU32::new_unchecked(code as u32)
49+
}))
50+
// in practice this should never happen
51+
.unwrap_or(UNKNOWN_ERROR)
52+
}
53+
}
54+
55+
#[cfg(not(target_env = "sgx"))]
56+
impl Into<io::Error> for Error {
57+
fn into(self) -> io::Error {
58+
match self {
59+
UNKNOWN_ERROR => io::Error::new(io::ErrorKind::Other,
60+
"getrandom error: unknown"),
61+
UNAVAILABLE_ERROR => io::Error::new(io::ErrorKind::Other,
62+
"getrandom error: entropy source is unavailable"),
63+
code => io::Error::from_raw_os_error(code.0.get() as i32),
64+
}
65+
}
66+
}
67+
68+
#[cfg(not(target_env = "sgx"))]
69+
impl error::Error for Error { }

src/freebsd.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ extern crate libc;
1111

1212
use super::Error;
1313
use core::ptr;
14+
use std::io;
1415

1516
pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
1617
let mib = [libc::CTL_KERN, libc::KERN_ARND];
@@ -24,7 +25,7 @@ pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
2425
)
2526
};
2627
if ret == -1 || len != chunk.len() {
27-
return Err(Error::Unknown);
28+
return Err(io::Error::last_os_error().into());
2829
}
2930
}
3031
Ok(())

src/lib.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,7 @@
77
// except according to those terms.
88
#![no_std]
99

10-
#[cfg(any(
11-
target_os = "android",
12-
target_os = "netbsd",
13-
target_os = "solaris",
14-
target_os = "redox",
15-
target_os = "dragonfly",
16-
target_os = "haiku",
17-
target_os = "emscripten",
18-
target_os = "linux",
19-
))]
10+
#[cfg(not(target_env = "sgx"))]
2011
#[macro_use] extern crate std;
2112

2213
#[cfg(any(
@@ -31,7 +22,7 @@
3122
))]
3223
mod utils;
3324
mod error;
34-
pub use error::Error;
25+
pub use error::{Error, UNKNOWN_ERROR, UNAVAILABLE_ERROR};
3526

3627
macro_rules! mod_use {
3728
($cond:meta, $module:ident) => {

src/linux_android.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
5858
match f {
5959
RngSource::GetRandom => syscall_getrandom(dest),
6060
RngSource::Device(f) => f.read_exact(dest),
61-
}
62-
}).map_err(|_| Error::Unknown)
61+
}.map_err(From::from)
62+
})
6363
})
6464
}
6565

src/macos.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
//! Implementation for MacOS / iOS
1010
use super::Error;
11+
use std::io;
1112

1213
// TODO: check correctness
1314
#[allow(non_upper_case_globals)]
@@ -29,7 +30,7 @@ pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
2930
)
3031
};
3132
if ret == -1 {
32-
Err(Error::Unknown)
33+
Err(io::Error::last_os_error().into())
3334
} else {
3435
Ok(())
3536
}

0 commit comments

Comments
 (0)