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