Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions axfs_devfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ extern crate alloc;

mod dir;
mod null;
mod urandom;
mod zero;

#[cfg(test)]
mod tests;

pub use self::dir::DirNode;
pub use self::null::NullDev;
pub use self::urandom::UrandomDev;
pub use self::zero::ZeroDev;

use alloc::sync::Arc;
Expand Down
69 changes: 69 additions & 0 deletions axfs_devfs/src/urandom.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use axfs_vfs::{VfsNodeAttr, VfsNodeOps, VfsNodePerm, VfsNodeType, VfsResult};
use core::sync::atomic::{AtomicU64, Ordering};

/// A urandom device behaves like `/dev/urandom`.
///
/// It produces random bytes when read.
pub struct UrandomDev {
seed: AtomicU64,
}

impl UrandomDev {
/// Create a new instance of the urandom device.
pub fn new() -> Self {
Self {
seed: AtomicU64::new(0xa2ce_a2ce),
}
}

/// LCG pseudo-random number generator
fn next_u64(&self) -> u64 {
let new_seed = self
.seed
.load(Ordering::SeqCst)
.wrapping_mul(6364136223846793005)
+ 1;
self.seed.store(new_seed, Ordering::SeqCst);
new_seed
}
}

impl Default for UrandomDev {
fn default() -> Self {
Self::new()
}
}

impl VfsNodeOps for UrandomDev {
fn get_attr(&self) -> VfsResult<VfsNodeAttr> {
Ok(VfsNodeAttr::new(
VfsNodePerm::default_file(),
VfsNodeType::CharDevice,
0,
0,
))
}

fn read_at(&self, _offset: u64, buf: &mut [u8]) -> VfsResult<usize> {
for chunk in buf.chunks_mut(8) {
let random_value = self.next_u64();
let bytes = random_value.to_ne_bytes();
for (i, byte) in chunk.iter_mut().enumerate() {
if i < bytes.len() {
*byte = bytes[i];
}
}
}
Ok(buf.len())
}

fn write_at(&self, _offset: u64, buf: &[u8]) -> VfsResult<usize> {
Ok(buf.len())
}

fn truncate(&self, _size: u64) -> VfsResult {
Ok(())
}

axfs_vfs::impl_vfs_non_dir_default! {}
}