10d48c3c9Slogin use alloc::sync::{Arc, Weak}; 20d48c3c9Slogin 30d48c3c9Slogin use crate::{ 40d48c3c9Slogin filesystem::{ 50d48c3c9Slogin devfs::{DeviceINode, DevFS}, 60d48c3c9Slogin vfs::{file::FileMode, FilePrivateData, IndexNode}, 70d48c3c9Slogin }, 8*676b8ef6SMork kerror, libs::rwlock::RwLock, syscall::SystemError, 90d48c3c9Slogin }; 100d48c3c9Slogin 110d48c3c9Slogin use super::{TtyCore, TtyError, TtyFileFlag, TtyFilePrivateData}; 120d48c3c9Slogin 130d48c3c9Slogin #[derive(Debug)] 140d48c3c9Slogin pub struct TtyDevice { 150d48c3c9Slogin core: TtyCore, 160d48c3c9Slogin fs: RwLock<Weak<DevFS>> 170d48c3c9Slogin 180d48c3c9Slogin } 190d48c3c9Slogin 200d48c3c9Slogin impl TtyDevice { 210d48c3c9Slogin pub fn new() -> Arc<TtyDevice> { 220d48c3c9Slogin return Arc::new(TtyDevice { 230d48c3c9Slogin core: TtyCore::new(), 240d48c3c9Slogin fs: RwLock::new(Weak::default()), 250d48c3c9Slogin }); 260d48c3c9Slogin } 270d48c3c9Slogin 280d48c3c9Slogin /// @brief 判断文件私有信息是否为TTY的私有信息 290d48c3c9Slogin #[inline] 300d48c3c9Slogin fn verify_file_private_data<'a>( 310d48c3c9Slogin &self, 320d48c3c9Slogin private_data: &'a mut FilePrivateData, 33*676b8ef6SMork ) -> Result<&'a mut TtyFilePrivateData, SystemError> { 340d48c3c9Slogin if let FilePrivateData::Tty(t) = private_data { 350d48c3c9Slogin return Ok(t); 360d48c3c9Slogin } 37*676b8ef6SMork return Err(SystemError::EIO); 380d48c3c9Slogin } 390d48c3c9Slogin } 400d48c3c9Slogin 410d48c3c9Slogin impl DeviceINode for TtyDevice { 420d48c3c9Slogin fn set_fs(&self, fs: alloc::sync::Weak<crate::filesystem::devfs::DevFS>) { 430d48c3c9Slogin *self.fs.write() = fs; 440d48c3c9Slogin } 450d48c3c9Slogin } 460d48c3c9Slogin 470d48c3c9Slogin impl IndexNode for TtyDevice { 48*676b8ef6SMork fn open(&self, data: &mut FilePrivateData, mode: &FileMode) -> Result<(), SystemError> { 490d48c3c9Slogin let p = TtyFilePrivateData::default(); 500d48c3c9Slogin *data = FilePrivateData::Tty(p); 510d48c3c9Slogin return Ok(()); 520d48c3c9Slogin } 530d48c3c9Slogin 540d48c3c9Slogin fn read_at( 550d48c3c9Slogin &self, 560d48c3c9Slogin offset: usize, 570d48c3c9Slogin len: usize, 580d48c3c9Slogin buf: &mut [u8], 590d48c3c9Slogin data: &mut crate::filesystem::vfs::FilePrivateData, 60*676b8ef6SMork ) -> Result<usize, SystemError> { 610d48c3c9Slogin let _data: &mut TtyFilePrivateData = match self.verify_file_private_data(data) { 620d48c3c9Slogin Ok(t) => t, 630d48c3c9Slogin Err(e) => { 640d48c3c9Slogin kerror!("Try to read tty device, but file private data type mismatch!"); 650d48c3c9Slogin return Err(e); 660d48c3c9Slogin } 670d48c3c9Slogin }; 680d48c3c9Slogin 690d48c3c9Slogin // 读取stdin队列 700d48c3c9Slogin let r: Result<usize, TtyError> = self.core.read_stdin(buf, true); 710d48c3c9Slogin if r.is_ok() { 720d48c3c9Slogin return Ok(r.unwrap()); 730d48c3c9Slogin } 740d48c3c9Slogin 750d48c3c9Slogin match r.unwrap_err() { 760d48c3c9Slogin TtyError::EOF(n) => { 770d48c3c9Slogin return Ok(n); 780d48c3c9Slogin } 790d48c3c9Slogin x => { 800d48c3c9Slogin kerror!("Error occurred when reading tty, msg={x:?}"); 81*676b8ef6SMork return Err(SystemError::ECONNABORTED); 820d48c3c9Slogin } 830d48c3c9Slogin } 840d48c3c9Slogin } 850d48c3c9Slogin 860d48c3c9Slogin fn write_at( 870d48c3c9Slogin &self, 880d48c3c9Slogin offset: usize, 890d48c3c9Slogin len: usize, 900d48c3c9Slogin buf: &[u8], 910d48c3c9Slogin data: &mut crate::filesystem::vfs::FilePrivateData, 92*676b8ef6SMork ) -> Result<usize, SystemError> { 930d48c3c9Slogin let data: &mut TtyFilePrivateData = match self.verify_file_private_data(data) { 940d48c3c9Slogin Ok(t) => t, 950d48c3c9Slogin Err(e) => { 960d48c3c9Slogin kerror!("Try to write tty device, but file private data type mismatch!"); 970d48c3c9Slogin return Err(e); 980d48c3c9Slogin } 990d48c3c9Slogin }; 1000d48c3c9Slogin 1010d48c3c9Slogin // 根据当前文件是stdout还是stderr,选择不同的发送方式 1020d48c3c9Slogin let r: Result<usize, TtyError> = if data.flags.contains(TtyFileFlag::STDOUT) { 1030d48c3c9Slogin self.core.stdout(buf, true) 1040d48c3c9Slogin } else if data.flags.contains(TtyFileFlag::STDERR) { 1050d48c3c9Slogin self.core.stderr(buf, true) 1060d48c3c9Slogin } else { 107*676b8ef6SMork return Err(SystemError::EPERM); 1080d48c3c9Slogin }; 1090d48c3c9Slogin 1100d48c3c9Slogin if r.is_ok() { 1110d48c3c9Slogin return Ok(r.unwrap()); 1120d48c3c9Slogin } 1130d48c3c9Slogin 1140d48c3c9Slogin let r: TtyError = r.unwrap_err(); 1150d48c3c9Slogin kerror!("Error occurred when writing tty deivce. Error msg={r:?}"); 116*676b8ef6SMork return Err(SystemError::EIO); 1170d48c3c9Slogin } 1180d48c3c9Slogin 119*676b8ef6SMork fn poll(&self) -> Result<crate::filesystem::vfs::PollStatus, SystemError> { 120*676b8ef6SMork return Err(SystemError::ENOTSUP); 1210d48c3c9Slogin } 1220d48c3c9Slogin 1230d48c3c9Slogin fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> { 1240d48c3c9Slogin return self.fs.read().upgrade().unwrap(); 1250d48c3c9Slogin } 1260d48c3c9Slogin 1270d48c3c9Slogin fn as_any_ref(&self) -> &dyn core::any::Any { 1280d48c3c9Slogin self 1290d48c3c9Slogin } 1300d48c3c9Slogin 131*676b8ef6SMork fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> { 132*676b8ef6SMork return Err(SystemError::ENOTSUP); 1330d48c3c9Slogin } 1340d48c3c9Slogin } 135