97 lines
2.3 KiB
Rust
97 lines
2.3 KiB
Rust
use core::{
|
|
cell::{LazyCell, RefCell},
|
|
sync::atomic::AtomicBool,
|
|
};
|
|
|
|
use alloc::{boxed::Box, rc::Rc};
|
|
use io::{IoBase, Read, Seek, Write};
|
|
|
|
use crate::{
|
|
data_structures::circular_buffer::CircularBuffer,
|
|
virtual_console::VirtualConsole,
|
|
virtual_fs::{VirtualFileSystem, VirtualNode},
|
|
};
|
|
|
|
pub const TTY_BUFFER_SIZE: usize = 4096; // 4Ko
|
|
pub static mut TTY0: LazyCell<Tty> = LazyCell::new(|| {
|
|
let tty = Tty::new();
|
|
TTY_INITIALIZED.store(true, core::sync::atomic::Ordering::Relaxed);
|
|
tty
|
|
});
|
|
pub static TTY_INITIALIZED: AtomicBool = AtomicBool::new(false);
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Tty {
|
|
pub buffer: Rc<RefCell<CircularBuffer<u8, TTY_BUFFER_SIZE>>>,
|
|
console: Rc<RefCell<VirtualConsole>>,
|
|
}
|
|
|
|
impl Tty {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
buffer: RefCell::new(CircularBuffer::new()).into(),
|
|
console: RefCell::new(VirtualConsole::new()).into(),
|
|
}
|
|
}
|
|
pub fn new_node(&'_ self) -> TtyNode<'_> {
|
|
TtyNode { tty: self }
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct TtyNode<'a> {
|
|
tty: &'a Tty,
|
|
}
|
|
|
|
impl VirtualFileSystem for Tty {
|
|
fn open(
|
|
&mut self,
|
|
path: &bffs::path::Path,
|
|
) -> Result<alloc::boxed::Box<dyn crate::virtual_fs::VirtualNode + '_>, ()> {
|
|
if !path.is_empty() {
|
|
Err(())
|
|
} else {
|
|
Ok(Box::new(self.new_node()))
|
|
}
|
|
}
|
|
}
|
|
|
|
impl IoBase for TtyNode<'_> {
|
|
type Error = ();
|
|
}
|
|
|
|
impl Read for TtyNode<'_> {
|
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
|
let mut buffer = self.tty.buffer.borrow_mut();
|
|
let max_len = buffer.len();
|
|
(0..buf.len().min(max_len)).for_each(|i| {
|
|
buf[i] = buffer.pop().unwrap();
|
|
});
|
|
Ok(buf.len().min(max_len))
|
|
}
|
|
}
|
|
|
|
impl Seek for TtyNode<'_> {
|
|
fn seek(&mut self, _pos: io::SeekFrom) -> Result<u64, Self::Error> {
|
|
unimplemented!()
|
|
}
|
|
}
|
|
|
|
impl Write for TtyNode<'_> {
|
|
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
|
|
critical_section::with(|_| {
|
|
self.tty
|
|
.console
|
|
.borrow_mut()
|
|
.write_str(str::from_utf8(buf).unwrap());
|
|
});
|
|
Ok(buf.len())
|
|
}
|
|
|
|
fn flush(&mut self) -> Result<(), Self::Error> {
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
impl VirtualNode for TtyNode<'_> {}
|