kernel_thread/fs/devfs/
stdio.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//! 标准输入输出使用的接口
//!
//! 目前标准输入输出等都使用一个结构体,通过设置不同的位置来确保只读,只写
use fs::INodeInterface;
use libc_core::types::StatMode;
use sel4::debug_print;
use syscalls::Errno;

use crate::device::uart::get_char;

/// 标准输入输出接口
pub struct StdConsole(u8);

impl StdConsole {
    /// 创建一个标准输入输出接口 [StdConsole]
    ///
    /// 根据不同的值,有不同的设置
    /// - `0` 只读
    /// - `1` | `2` 只写
    /// - `> 2` 可读可写
    pub const fn new(idx: u8) -> Self {
        Self(idx)
    }
}

impl INodeInterface for StdConsole {
    fn readat(&self, _offset: usize, buffer: &mut [u8]) -> vfscore::VfsResult<usize> {
        if self.0 != 0 && self.0 <= 2 {
            return Err(Errno::EPERM);
        }
        match get_char() {
            Some(c) => {
                buffer[0] = c;
                Ok(1)
            }
            None => Ok(0),
        }
    }

    fn writeat(&self, _offset: usize, buffer: &[u8]) -> vfscore::VfsResult<usize> {
        if self.0 == 0 {
            return Err(Errno::EPERM);
        }
        // srv_gate::UART_IMPLS[0].lock().puts(data);
        // debug_println!("{}", );
        buffer.iter().for_each(|x| debug_print!("{}", *x as char));
        Ok(buffer.len())
    }

    fn stat(&self, stat: &mut libc_core::types::Stat) -> vfscore::VfsResult<()> {
        stat.dev = 0;
        stat.ino = 1; // TODO: convert path to number(ino)
        stat.mode = StatMode::CHAR; // TODO: add access mode
        stat.nlink = 1;
        stat.uid = 1000;
        stat.gid = 1000;
        stat.size = 0;
        stat.blksize = 512;
        stat.blocks = 0;
        stat.rdev = 0; // TODO: add device id
        Ok(())
    }
}