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