1 use alloc::sync::{Arc, Weak}; 2 3 use crate::{ 4 filesystem::{ 5 devfs::{DeviceINode, DevFS}, 6 vfs::{file::FileMode, FilePrivateData, IndexNode}, 7 }, 8 kerror, libs::rwlock::RwLock, syscall::SystemError, 9 }; 10 11 use super::{TtyCore, TtyError, TtyFileFlag, TtyFilePrivateData}; 12 13 #[derive(Debug)] 14 pub struct TtyDevice { 15 core: TtyCore, 16 fs: RwLock<Weak<DevFS>> 17 18 } 19 20 impl TtyDevice { 21 pub fn new() -> Arc<TtyDevice> { 22 return Arc::new(TtyDevice { 23 core: TtyCore::new(), 24 fs: RwLock::new(Weak::default()), 25 }); 26 } 27 28 /// @brief 判断文件私有信息是否为TTY的私有信息 29 #[inline] 30 fn verify_file_private_data<'a>( 31 &self, 32 private_data: &'a mut FilePrivateData, 33 ) -> Result<&'a mut TtyFilePrivateData, SystemError> { 34 if let FilePrivateData::Tty(t) = private_data { 35 return Ok(t); 36 } 37 return Err(SystemError::EIO); 38 } 39 } 40 41 impl DeviceINode for TtyDevice { 42 fn set_fs(&self, fs: alloc::sync::Weak<crate::filesystem::devfs::DevFS>) { 43 *self.fs.write() = fs; 44 } 45 } 46 47 impl IndexNode for TtyDevice { 48 fn open(&self, data: &mut FilePrivateData, mode: &FileMode) -> Result<(), SystemError> { 49 let p = TtyFilePrivateData::default(); 50 *data = FilePrivateData::Tty(p); 51 return Ok(()); 52 } 53 54 fn read_at( 55 &self, 56 offset: usize, 57 len: usize, 58 buf: &mut [u8], 59 data: &mut crate::filesystem::vfs::FilePrivateData, 60 ) -> Result<usize, SystemError> { 61 let _data: &mut TtyFilePrivateData = match self.verify_file_private_data(data) { 62 Ok(t) => t, 63 Err(e) => { 64 kerror!("Try to read tty device, but file private data type mismatch!"); 65 return Err(e); 66 } 67 }; 68 69 // 读取stdin队列 70 let r: Result<usize, TtyError> = self.core.read_stdin(buf, true); 71 if r.is_ok() { 72 return Ok(r.unwrap()); 73 } 74 75 match r.unwrap_err() { 76 TtyError::EOF(n) => { 77 return Ok(n); 78 } 79 x => { 80 kerror!("Error occurred when reading tty, msg={x:?}"); 81 return Err(SystemError::ECONNABORTED); 82 } 83 } 84 } 85 86 fn write_at( 87 &self, 88 offset: usize, 89 len: usize, 90 buf: &[u8], 91 data: &mut crate::filesystem::vfs::FilePrivateData, 92 ) -> Result<usize, SystemError> { 93 let data: &mut TtyFilePrivateData = match self.verify_file_private_data(data) { 94 Ok(t) => t, 95 Err(e) => { 96 kerror!("Try to write tty device, but file private data type mismatch!"); 97 return Err(e); 98 } 99 }; 100 101 // 根据当前文件是stdout还是stderr,选择不同的发送方式 102 let r: Result<usize, TtyError> = if data.flags.contains(TtyFileFlag::STDOUT) { 103 self.core.stdout(buf, true) 104 } else if data.flags.contains(TtyFileFlag::STDERR) { 105 self.core.stderr(buf, true) 106 } else { 107 return Err(SystemError::EPERM); 108 }; 109 110 if r.is_ok() { 111 return Ok(r.unwrap()); 112 } 113 114 let r: TtyError = r.unwrap_err(); 115 kerror!("Error occurred when writing tty deivce. Error msg={r:?}"); 116 return Err(SystemError::EIO); 117 } 118 119 fn poll(&self) -> Result<crate::filesystem::vfs::PollStatus, SystemError> { 120 return Err(SystemError::ENOTSUP); 121 } 122 123 fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> { 124 return self.fs.read().upgrade().unwrap(); 125 } 126 127 fn as_any_ref(&self) -> &dyn core::any::Any { 128 self 129 } 130 131 fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> { 132 return Err(SystemError::ENOTSUP); 133 } 134 } 135