Skip to content

Commit 100f3b9

Browse files
author
Jiajie Chen
committed
Implement /dev/{u,}random
1 parent 655c1f1 commit 100f3b9

File tree

6 files changed

+106
-16
lines changed

6 files changed

+106
-16
lines changed

kernel/src/fs/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub use self::file::*;
1313
pub use self::file_like::*;
1414
pub use self::pipe::Pipe;
1515
pub use self::pseudo::*;
16+
pub use self::random::*;
1617
pub use self::stdio::{STDIN, STDOUT};
1718
pub use self::vga::*;
1819

@@ -22,6 +23,7 @@ mod file_like;
2223
mod ioctl;
2324
mod pipe;
2425
mod pseudo;
26+
mod random;
2527
mod stdio;
2628
pub mod vga;
2729

@@ -81,6 +83,8 @@ lazy_static! {
8183
let devfs = DevFS::new();
8284
devfs.add("null", Arc::new(NullINode::default())).expect("failed to mknod /dev/null");
8385
devfs.add("zero", Arc::new(ZeroINode::default())).expect("failed to mknod /dev/zero");
86+
devfs.add("random", Arc::new(RandomINode::new(false))).expect("failed to mknod /dev/zero");
87+
devfs.add("urandom", Arc::new(RandomINode::new(true))).expect("failed to mknod /dev/zero");
8488

8589
// mount DevFS at /dev
8690
let dev = root.find(true, "dev").unwrap_or_else(|_| {

kernel/src/fs/pipe.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,7 @@ impl INode for Pipe {
104104
})
105105
}
106106

107-
fn as_any_ref(&self) -> &dyn Any { self }
107+
fn as_any_ref(&self) -> &dyn Any {
108+
self
109+
}
108110
}

kernel/src/fs/pseudo.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,7 @@ impl INode for Pseudo {
5656
rdev: 0,
5757
})
5858
}
59-
fn as_any_ref(&self) -> &dyn Any { self }
59+
fn as_any_ref(&self) -> &dyn Any {
60+
self
61+
}
6062
}

kernel/src/fs/random.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//! Implement INode for RandomINode
2+
3+
use alloc::{collections::vec_deque::VecDeque, string::String, sync::Arc};
4+
use core::any::Any;
5+
6+
use rcore_fs::vfs::*;
7+
8+
use crate::sync::Condvar;
9+
use crate::sync::SpinNoIrqLock as Mutex;
10+
11+
pub struct RandomINodeData {
12+
seed: u32,
13+
}
14+
15+
#[derive(Clone)]
16+
pub struct RandomINode {
17+
data: Arc<Mutex<RandomINodeData>>,
18+
secure: bool,
19+
}
20+
21+
impl RandomINode {
22+
// urandom -> secure=true
23+
// random -> secure=false
24+
pub fn new(secure: bool) -> RandomINode {
25+
RandomINode {
26+
secure,
27+
data: Arc::new(Mutex::new(RandomINodeData { seed: 1 })),
28+
}
29+
}
30+
}
31+
32+
impl INode for RandomINode {
33+
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> Result<usize> {
34+
if buf.len() > 0 {
35+
let mut data = self.data.lock();
36+
// from K&R
37+
for i in 0..buf.len() {
38+
data.seed = data.seed.wrapping_mul(1103515245).wrapping_add(12345);
39+
buf[i] = (data.seed / 65536) as u8;
40+
}
41+
Ok(buf.len())
42+
} else {
43+
Ok(0)
44+
}
45+
}
46+
47+
fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result<usize> {
48+
Err(FsError::NotSupported)
49+
}
50+
51+
fn poll(&self) -> Result<PollStatus> {
52+
Ok(PollStatus {
53+
read: true,
54+
write: false,
55+
error: false,
56+
})
57+
}
58+
59+
fn metadata(&self) -> Result<Metadata> {
60+
Ok(Metadata {
61+
dev: 1,
62+
inode: 1,
63+
size: 0,
64+
blk_size: 0,
65+
blocks: 0,
66+
atime: Timespec { sec: 0, nsec: 0 },
67+
mtime: Timespec { sec: 0, nsec: 0 },
68+
ctime: Timespec { sec: 0, nsec: 0 },
69+
type_: FileType::CharDevice,
70+
mode: 0o666,
71+
nlinks: 1,
72+
uid: 0,
73+
gid: 0,
74+
rdev: make_rdev(1, if self.secure { 9 } else { 8 }),
75+
})
76+
}
77+
78+
fn as_any_ref(&self) -> &dyn Any {
79+
self
80+
}
81+
}

kernel/src/fs/stdio.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ lazy_static! {
5353
pub static ref STDOUT: Arc<Stdout> = Arc::new(Stdout::default());
5454
}
5555

56-
5756
impl INode for Stdin {
5857
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
5958
if self.can_read() {
@@ -78,19 +77,19 @@ impl INode for Stdin {
7877
TCGETS | TIOCGWINSZ | TIOCSPGRP => {
7978
// pretend to be tty
8079
Ok(())
81-
},
80+
}
8281
TIOCGPGRP => {
8382
// pretend to be have a tty process group
8483
// TODO: verify pointer
85-
unsafe {
86-
*(data as *mut u32) = 0
87-
};
84+
unsafe { *(data as *mut u32) = 0 };
8885
Ok(())
8986
}
90-
_ => Err(FsError::NotSupported)
87+
_ => Err(FsError::NotSupported),
9188
}
9289
}
93-
fn as_any_ref(&self) -> &dyn Any { self }
90+
fn as_any_ref(&self) -> &dyn Any {
91+
self
92+
}
9493
}
9594

9695
impl INode for Stdout {
@@ -116,17 +115,17 @@ impl INode for Stdout {
116115
TCGETS | TIOCGWINSZ | TIOCSPGRP => {
117116
// pretend to be tty
118117
Ok(())
119-
},
118+
}
120119
TIOCGPGRP => {
121120
// pretend to be have a tty process group
122121
// TODO: verify pointer
123-
unsafe {
124-
*(data as *mut u32) = 0
125-
};
122+
unsafe { *(data as *mut u32) = 0 };
126123
Ok(())
127124
}
128-
_ => Err(FsError::NotSupported)
125+
_ => Err(FsError::NotSupported),
129126
}
130127
}
131-
fn as_any_ref(&self) -> &dyn Any { self }
128+
fn as_any_ref(&self) -> &dyn Any {
129+
self
130+
}
132131
}

kernel/src/fs/vga.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ impl INode for Vga {
8080
//let fb_fix_info = unsafe{ &mut *(data as *mut fb_fix_screeninfo) };
8181
//Ok(())
8282
}
83-
fn as_any_ref(&self) -> &dyn Any { self }
83+
fn as_any_ref(&self) -> &dyn Any {
84+
self
85+
}
8486
}
8587

8688
const FBIOGET_FSCREENINFO: u32 = 0x4602;

0 commit comments

Comments
 (0)