    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

    //! File and filesystem-related syscalls
    use crate::mm::translated_byte_buffer;
    use crate::sbi::console_getchar;
    use crate::task::{current_user_token, suspend_current_and_run_next};

    const FD_STDIN: usize = 0;
    const FD_STDOUT: usize = 1;

    pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
        match fd {
            FD_STDOUT => {
                let buffers = translated_byte_buffer(current_user_token(), buf, len);
                for buffer in buffers {
                    print!("{}", core::str::from_utf8(buffer).unwrap());
                }
                len as isize
            }
            _ => {
                panic!("Unsupported fd in sys_write!");
            }
        }
    }

    pub fn sys_read(fd: usize, buf: *const u8, len: usize) -> isize {
        match fd {
            FD_STDIN => {
                assert_eq!(len, 1, "Only support len = 1 in sys_read!");
                let mut c: usize;
                loop {
                    c = console_getchar();
                    if c == 0 {
                        suspend_current_and_run_next();
                        continue;
                    } else {
                        break;
                    }
                }
                let ch = c as u8;
                let mut buffers = translated_byte_buffer(current_user_token(), buf, len);
                unsafe {
                    buffers[0].as_mut_ptr().write_volatile(ch);
                }
                1
            }
            _ => {
                panic!("Unsupported fd in sys_read!");
            }
        }
    }