1use axfs_vfs::{VfsNodeAttr, VfsNodeOps, VfsNodePerm, VfsNodeType, VfsResult};
2use core::sync::atomic::{AtomicU64, Ordering};
3
4pub struct UrandomDev {
8 seed: AtomicU64,
9}
10
11impl UrandomDev {
12 pub const fn new(seed: u64) -> Self {
14 Self {
15 seed: AtomicU64::new(seed),
16 }
17 }
18
19 fn new_with_default_seed() -> Self {
21 Self::new(0xa2ce_a2ce)
22 }
23
24 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
36impl Default for UrandomDev {
37 fn default() -> Self {
38 Self::new_with_default_seed()
39 }
40}
41
42impl 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}