Skip to content

Commit 1551303

Browse files
add UrandomDev (#2)
1 parent 0b21a16 commit 1551303

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

axfs_devfs/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ extern crate alloc;
88

99
mod dir;
1010
mod null;
11+
mod urandom;
1112
mod zero;
1213

1314
#[cfg(test)]
1415
mod tests;
1516

1617
pub use self::dir::DirNode;
1718
pub use self::null::NullDev;
19+
pub use self::urandom::UrandomDev;
1820
pub use self::zero::ZeroDev;
1921

2022
use alloc::sync::Arc;

axfs_devfs/src/urandom.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use axfs_vfs::{VfsNodeAttr, VfsNodeOps, VfsNodePerm, VfsNodeType, VfsResult};
2+
use core::sync::atomic::{AtomicU64, Ordering};
3+
4+
/// A urandom device behaves like `/dev/urandom`.
5+
///
6+
/// It produces random bytes when read.
7+
pub struct UrandomDev {
8+
seed: AtomicU64,
9+
}
10+
11+
impl UrandomDev {
12+
/// Create a new instance of the urandom device.
13+
pub const fn new(seed: u64) -> Self {
14+
Self {
15+
seed: AtomicU64::new(seed),
16+
}
17+
}
18+
19+
/// Create a new instance with a default seed.
20+
fn new_with_default_seed() -> Self {
21+
Self::new(0xa2ce_a2ce)
22+
}
23+
24+
/// LCG pseudo-random number generator
25+
fn next_u64(&self) -> u64 {
26+
let new_seed = self
27+
.seed
28+
.load(Ordering::SeqCst)
29+
.wrapping_mul(6364136223846793005)
30+
+ 1;
31+
self.seed.store(new_seed, Ordering::SeqCst);
32+
new_seed
33+
}
34+
}
35+
36+
impl Default for UrandomDev {
37+
fn default() -> Self {
38+
Self::new_with_default_seed()
39+
}
40+
}
41+
42+
impl VfsNodeOps for UrandomDev {
43+
fn get_attr(&self) -> VfsResult<VfsNodeAttr> {
44+
Ok(VfsNodeAttr::new(
45+
VfsNodePerm::default_file(),
46+
VfsNodeType::CharDevice,
47+
0,
48+
0,
49+
))
50+
}
51+
52+
fn read_at(&self, _offset: u64, buf: &mut [u8]) -> VfsResult<usize> {
53+
for chunk in buf.chunks_mut(8) {
54+
let random_value = self.next_u64();
55+
let bytes = random_value.to_ne_bytes();
56+
for (i, byte) in chunk.iter_mut().enumerate() {
57+
if i < bytes.len() {
58+
*byte = bytes[i];
59+
}
60+
}
61+
}
62+
Ok(buf.len())
63+
}
64+
65+
fn write_at(&self, _offset: u64, buf: &[u8]) -> VfsResult<usize> {
66+
Ok(buf.len())
67+
}
68+
69+
fn truncate(&self, _size: u64) -> VfsResult {
70+
Ok(())
71+
}
72+
73+
axfs_vfs::impl_vfs_non_dir_default! {}
74+
}

0 commit comments

Comments
 (0)