Skip to content

Commit 9a385f1

Browse files
authored
Add VxWorks support (#86)
1 parent 2fa1bba commit 9a385f1

File tree

6 files changed

+50
-2
lines changed

6 files changed

+50
-2
lines changed

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ matrix:
139139
- cargo xbuild --target=x86_64-unknown-uefi
140140
- cargo xbuild --target=x86_64-unknown-hermit
141141
- cargo xbuild --target=x86_64-unknown-l4re-uclibc
142+
- cargo xbuild --target=x86_64-wrs-vxworks
142143
# also test minimum dependency versions are usable
143144
- cargo generate-lockfile -Z minimal-versions
144145
- cargo build --target=x86_64-sun-solaris

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ cfg-if = "0.1.2"
2222
compiler_builtins = { version = "0.1", optional = true }
2323
core = { version = "1.0", optional = true, package = "rustc-std-workspace-core" }
2424

25-
[target.'cfg(any(unix, target_os = "redox"))'.dependencies]
26-
libc = { version = "0.2.62", default-features = false }
25+
[target.'cfg(unix)'.dependencies]
26+
libc = { version = "0.2.64", default-features = false }
2727

2828
[target.'cfg(target_os = "wasi")'.dependencies]
2929
wasi = "0.7"

src/error.rs

+2
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ pub(crate) const BINDGEN_CRYPTO_UNDEF: Error = internal_error!(7);
145145
pub(crate) const BINDGEN_GRV_UNDEF: Error = internal_error!(8);
146146
pub(crate) const STDWEB_NO_RNG: Error = internal_error!(9);
147147
pub(crate) const STDWEB_RNG_FAILED: Error = internal_error!(10);
148+
pub(crate) const RAND_SECURE_FATAL: Error = internal_error!(11);
148149

149150
fn internal_desc(error: Error) -> Option<&'static str> {
150151
match error {
@@ -159,6 +160,7 @@ fn internal_desc(error: Error) -> Option<&'static str> {
159160
BINDGEN_GRV_UNDEF => Some("wasm-bindgen: crypto.getRandomValues is undefined"),
160161
STDWEB_NO_RNG => Some("stdweb: no randomness source available"),
161162
STDWEB_RNG_FAILED => Some("stdweb: failed to get randomness"),
163+
RAND_SECURE_FATAL => Some("randSecure: random number generator module is not initialized"),
162164
_ => None,
163165
}
164166
}

src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
//! | Haiku | `/dev/random` (identical to `/dev/urandom`)
2828
//! | L4RE, SGX, UEFI | [RDRAND][18]
2929
//! | Hermit | [RDRAND][18] as [`sys_rand`][22] is currently broken.
30+
//! | VxWorks | `randABytes` after checking entropy pool initialization with `randSecure`
3031
//! | Web browsers | [`Crypto.getRandomValues`][14] (see [Support for WebAssembly and ams.js][14])
3132
//! | Node.js | [`crypto.randomBytes`][15] (see [Support for WebAssembly and ams.js][16])
3233
//! | WASI | [`__wasi_random_get`][17]
@@ -160,6 +161,10 @@ pub use crate::error::Error;
160161
#[allow(dead_code)]
161162
mod util;
162163

164+
#[cfg(target_os = "vxworks")]
165+
#[allow(dead_code)]
166+
mod util_libc;
167+
163168
cfg_if! {
164169
// Unlike the other Unix, Fuchsia and iOS don't use the libc to make any calls.
165170
if #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "emscripten",
@@ -221,6 +226,8 @@ cfg_if! {
221226
#[path = "solaris_illumos.rs"] mod imp;
222227
} else if #[cfg(target_os = "wasi")] {
223228
#[path = "wasi.rs"] mod imp;
229+
} else if #[cfg(target_os = "vxworks")] {
230+
#[path = "vxworks.rs"] mod imp;
224231
} else if #[cfg(all(windows, getrandom_uwp))] {
225232
#[path = "windows_uwp.rs"] mod imp;
226233
} else if #[cfg(windows)] {

src/util_libc.rs

+3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ cfg_if! {
2626
}
2727

2828
pub fn last_os_error() -> Error {
29+
#[cfg(not(target_os = "vxworks"))]
2930
let errno = unsafe { *errno_location() };
31+
#[cfg(target_os = "vxworks")]
32+
let errno = unsafe { libc::errnoGet() };
3033
if errno > 0 {
3134
Error::from(NonZeroU32::new(errno as u32).unwrap())
3235
} else {

src/vxworks.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2018 Developers of the Rand project.
2+
//
3+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6+
// option. This file may not be copied, modified, or distributed
7+
// except according to those terms.
8+
9+
//! Implementation for VxWorks
10+
use crate::error::{Error, RAND_SECURE_FATAL};
11+
use crate::util_libc::last_os_error;
12+
use core::sync::atomic::{AtomicBool, Ordering::Relaxed};
13+
14+
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
15+
static RNG_INIT: AtomicBool = AtomicBool::new(false);
16+
while !RNG_INIT.load(Relaxed) {
17+
let ret = unsafe { libc::randSecure() };
18+
if ret < 0 {
19+
return Err(RAND_SECURE_FATAL);
20+
} else if ret > 0 {
21+
RNG_INIT.store(true, Relaxed);
22+
break;
23+
}
24+
unsafe { libc::usleep(10) };
25+
}
26+
27+
// Prevent overflow of i32
28+
for chunk in dest.chunks_mut(i32::max_value() as usize) {
29+
let ret = unsafe { libc::randABytes(chunk.as_mut_ptr(), chunk.len() as i32) };
30+
if ret != 0 {
31+
return Err(last_os_error());
32+
}
33+
}
34+
Ok(())
35+
}

0 commit comments

Comments
 (0)