xref: /DragonOS/kernel/src/driver/tty/tty_device.rs (revision 676b8ef62e1a0a1e52d65b40c53c1636a2954040)
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