xref: /DragonOS/kernel/src/driver/tty/tty_core.rs (revision 52da9a59374752b4d01907b052135a0d317781dd)
1*52da9a59SGnoCiYeH use core::{fmt::Debug, sync::atomic::AtomicBool};
2*52da9a59SGnoCiYeH 
3*52da9a59SGnoCiYeH use alloc::{string::String, sync::Arc, vec::Vec};
4*52da9a59SGnoCiYeH use system_error::SystemError;
5*52da9a59SGnoCiYeH 
6*52da9a59SGnoCiYeH use crate::{
7*52da9a59SGnoCiYeH     libs::{
8*52da9a59SGnoCiYeH         rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard},
9*52da9a59SGnoCiYeH         spinlock::{SpinLock, SpinLockGuard},
10*52da9a59SGnoCiYeH         wait_queue::EventWaitQueue,
11*52da9a59SGnoCiYeH     },
12*52da9a59SGnoCiYeH     mm::VirtAddr,
13*52da9a59SGnoCiYeH     net::event_poll::EPollEventType,
14*52da9a59SGnoCiYeH     process::Pid,
15*52da9a59SGnoCiYeH     syscall::user_access::UserBufferWriter,
16*52da9a59SGnoCiYeH };
17*52da9a59SGnoCiYeH 
18*52da9a59SGnoCiYeH use super::{
19*52da9a59SGnoCiYeH     termios::{ControlMode, PosixTermios, Termios, TtySetTermiosOpt, WindowSize},
20*52da9a59SGnoCiYeH     tty_driver::{TtyDriver, TtyDriverSubType, TtyDriverType, TtyOperation},
21*52da9a59SGnoCiYeH     tty_ldisc::{
22*52da9a59SGnoCiYeH         ntty::{NTtyData, NTtyLinediscipline},
23*52da9a59SGnoCiYeH         TtyLineDiscipline,
24*52da9a59SGnoCiYeH     },
25*52da9a59SGnoCiYeH     tty_port::TtyPort,
26*52da9a59SGnoCiYeH     virtual_terminal::{virtual_console::VirtualConsoleData, VIRT_CONSOLES},
27*52da9a59SGnoCiYeH };
28*52da9a59SGnoCiYeH 
29*52da9a59SGnoCiYeH #[derive(Debug)]
30*52da9a59SGnoCiYeH pub struct TtyCore {
31*52da9a59SGnoCiYeH     core: TtyCoreData,
32*52da9a59SGnoCiYeH     /// 线路规程函数集
33*52da9a59SGnoCiYeH     line_discipline: Arc<dyn TtyLineDiscipline>,
34*52da9a59SGnoCiYeH }
35*52da9a59SGnoCiYeH 
36*52da9a59SGnoCiYeH impl TtyCore {
37*52da9a59SGnoCiYeH     pub fn new(driver: Arc<TtyDriver>, index: usize) -> Arc<Self> {
38*52da9a59SGnoCiYeH         let name = driver.tty_line_name(index);
39*52da9a59SGnoCiYeH         let termios = driver.init_termios();
40*52da9a59SGnoCiYeH         let core = TtyCoreData {
41*52da9a59SGnoCiYeH             tty_driver: driver,
42*52da9a59SGnoCiYeH             termios: RwLock::new(termios),
43*52da9a59SGnoCiYeH             name,
44*52da9a59SGnoCiYeH             flags: RwLock::new(TtyFlag::empty()),
45*52da9a59SGnoCiYeH             count: RwLock::new(0),
46*52da9a59SGnoCiYeH             window_size: RwLock::new(WindowSize::default()),
47*52da9a59SGnoCiYeH             read_wq: EventWaitQueue::new(),
48*52da9a59SGnoCiYeH             write_wq: EventWaitQueue::new(),
49*52da9a59SGnoCiYeH             port: RwLock::new(None),
50*52da9a59SGnoCiYeH             index,
51*52da9a59SGnoCiYeH             ctrl: SpinLock::new(TtyContorlInfo::default()),
52*52da9a59SGnoCiYeH             closing: AtomicBool::new(false),
53*52da9a59SGnoCiYeH             flow: SpinLock::new(TtyFlowState::default()),
54*52da9a59SGnoCiYeH         };
55*52da9a59SGnoCiYeH 
56*52da9a59SGnoCiYeH         return Arc::new(Self {
57*52da9a59SGnoCiYeH             core,
58*52da9a59SGnoCiYeH             line_discipline: Arc::new(NTtyLinediscipline {
59*52da9a59SGnoCiYeH                 data: SpinLock::new(NTtyData::new()),
60*52da9a59SGnoCiYeH             }),
61*52da9a59SGnoCiYeH         });
62*52da9a59SGnoCiYeH     }
63*52da9a59SGnoCiYeH 
64*52da9a59SGnoCiYeH     #[inline]
65*52da9a59SGnoCiYeH     pub fn core(&self) -> &TtyCoreData {
66*52da9a59SGnoCiYeH         return &self.core;
67*52da9a59SGnoCiYeH     }
68*52da9a59SGnoCiYeH 
69*52da9a59SGnoCiYeH     #[inline]
70*52da9a59SGnoCiYeH     pub fn ldisc(&self) -> Arc<dyn TtyLineDiscipline> {
71*52da9a59SGnoCiYeH         self.line_discipline.clone()
72*52da9a59SGnoCiYeH     }
73*52da9a59SGnoCiYeH 
74*52da9a59SGnoCiYeH     pub fn reopen(&self) -> Result<(), SystemError> {
75*52da9a59SGnoCiYeH         let tty_core = self.core();
76*52da9a59SGnoCiYeH         let driver = tty_core.driver();
77*52da9a59SGnoCiYeH 
78*52da9a59SGnoCiYeH         if driver.tty_driver_type() == TtyDriverType::Pty
79*52da9a59SGnoCiYeH             && driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster
80*52da9a59SGnoCiYeH         {
81*52da9a59SGnoCiYeH             return Err(SystemError::EIO);
82*52da9a59SGnoCiYeH         }
83*52da9a59SGnoCiYeH 
84*52da9a59SGnoCiYeH         // if *tty_core.count.read() == 0 {
85*52da9a59SGnoCiYeH         //     return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
86*52da9a59SGnoCiYeH         // }
87*52da9a59SGnoCiYeH 
88*52da9a59SGnoCiYeH         // TODO 判断flags
89*52da9a59SGnoCiYeH 
90*52da9a59SGnoCiYeH         tty_core.add_count();
91*52da9a59SGnoCiYeH 
92*52da9a59SGnoCiYeH         Ok(())
93*52da9a59SGnoCiYeH     }
94*52da9a59SGnoCiYeH 
95*52da9a59SGnoCiYeH     #[inline]
96*52da9a59SGnoCiYeH     pub fn set_port(&self, port: Arc<dyn TtyPort>) {
97*52da9a59SGnoCiYeH         *self.core.port.write() = Some(port);
98*52da9a59SGnoCiYeH     }
99*52da9a59SGnoCiYeH 
100*52da9a59SGnoCiYeH     pub fn tty_start(&self) {
101*52da9a59SGnoCiYeH         let mut flow = self.core.flow.lock_irqsave();
102*52da9a59SGnoCiYeH         if !flow.stopped || flow.tco_stopped {
103*52da9a59SGnoCiYeH             return;
104*52da9a59SGnoCiYeH         }
105*52da9a59SGnoCiYeH 
106*52da9a59SGnoCiYeH         flow.stopped = false;
107*52da9a59SGnoCiYeH         let _ = self.start(self.core());
108*52da9a59SGnoCiYeH         self.tty_wakeup();
109*52da9a59SGnoCiYeH     }
110*52da9a59SGnoCiYeH 
111*52da9a59SGnoCiYeH     pub fn tty_stop(&self) {
112*52da9a59SGnoCiYeH         let mut flow = self.core.flow.lock_irqsave();
113*52da9a59SGnoCiYeH         if flow.stopped {
114*52da9a59SGnoCiYeH             return;
115*52da9a59SGnoCiYeH         }
116*52da9a59SGnoCiYeH         flow.stopped = true;
117*52da9a59SGnoCiYeH 
118*52da9a59SGnoCiYeH         let _ = self.stop(self.core());
119*52da9a59SGnoCiYeH     }
120*52da9a59SGnoCiYeH 
121*52da9a59SGnoCiYeH     pub fn tty_wakeup(&self) {
122*52da9a59SGnoCiYeH         if self.core.flags.read().contains(TtyFlag::DO_WRITE_WAKEUP) {
123*52da9a59SGnoCiYeH             let _ = self.ldisc().write_wakeup(self.core());
124*52da9a59SGnoCiYeH         }
125*52da9a59SGnoCiYeH 
126*52da9a59SGnoCiYeH         self.core()
127*52da9a59SGnoCiYeH             .write_wq
128*52da9a59SGnoCiYeH             .wakeup(EPollEventType::EPOLLOUT.bits() as u64);
129*52da9a59SGnoCiYeH     }
130*52da9a59SGnoCiYeH 
131*52da9a59SGnoCiYeH     pub fn tty_mode_ioctl(
132*52da9a59SGnoCiYeH         &self,
133*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
134*52da9a59SGnoCiYeH         cmd: u32,
135*52da9a59SGnoCiYeH         arg: usize,
136*52da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
137*52da9a59SGnoCiYeH         match cmd {
138*52da9a59SGnoCiYeH             TtyIoctlCmd::TCGETS => {
139*52da9a59SGnoCiYeH                 let termios = PosixTermios::from_kernel_termios(self.core.termios().clone());
140*52da9a59SGnoCiYeH                 let mut user_writer = UserBufferWriter::new(
141*52da9a59SGnoCiYeH                     VirtAddr::new(arg).as_ptr::<PosixTermios>(),
142*52da9a59SGnoCiYeH                     core::mem::size_of::<PosixTermios>(),
143*52da9a59SGnoCiYeH                     true,
144*52da9a59SGnoCiYeH                 )?;
145*52da9a59SGnoCiYeH 
146*52da9a59SGnoCiYeH                 user_writer.copy_one_to_user(&termios, 0)?;
147*52da9a59SGnoCiYeH                 return Ok(0);
148*52da9a59SGnoCiYeH             }
149*52da9a59SGnoCiYeH             TtyIoctlCmd::TCSETSW => {
150*52da9a59SGnoCiYeH                 return self.core_set_termios(
151*52da9a59SGnoCiYeH                     tty,
152*52da9a59SGnoCiYeH                     VirtAddr::new(arg),
153*52da9a59SGnoCiYeH                     TtySetTermiosOpt::TERMIOS_WAIT | TtySetTermiosOpt::TERMIOS_OLD,
154*52da9a59SGnoCiYeH                 );
155*52da9a59SGnoCiYeH             }
156*52da9a59SGnoCiYeH             _ => {
157*52da9a59SGnoCiYeH                 return Err(SystemError::ENOIOCTLCMD);
158*52da9a59SGnoCiYeH             }
159*52da9a59SGnoCiYeH         }
160*52da9a59SGnoCiYeH     }
161*52da9a59SGnoCiYeH 
162*52da9a59SGnoCiYeH     pub fn core_set_termios(
163*52da9a59SGnoCiYeH         &self,
164*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
165*52da9a59SGnoCiYeH         arg: VirtAddr,
166*52da9a59SGnoCiYeH         opt: TtySetTermiosOpt,
167*52da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
168*52da9a59SGnoCiYeH         let tmp_termios = self.core().termios().clone();
169*52da9a59SGnoCiYeH 
170*52da9a59SGnoCiYeH         if opt.contains(TtySetTermiosOpt::TERMIOS_TERMIO) {
171*52da9a59SGnoCiYeH             todo!()
172*52da9a59SGnoCiYeH         } else {
173*52da9a59SGnoCiYeH             let mut user_writer = UserBufferWriter::new(
174*52da9a59SGnoCiYeH                 arg.as_ptr::<PosixTermios>(),
175*52da9a59SGnoCiYeH                 core::mem::size_of::<PosixTermios>(),
176*52da9a59SGnoCiYeH                 true,
177*52da9a59SGnoCiYeH             )?;
178*52da9a59SGnoCiYeH 
179*52da9a59SGnoCiYeH             user_writer.copy_one_to_user(&tmp_termios, 0)?;
180*52da9a59SGnoCiYeH         }
181*52da9a59SGnoCiYeH 
182*52da9a59SGnoCiYeH         if opt.contains(TtySetTermiosOpt::TERMIOS_FLUSH) {
183*52da9a59SGnoCiYeH             let ld = self.ldisc();
184*52da9a59SGnoCiYeH             let _ = ld.flush_buffer(tty.clone());
185*52da9a59SGnoCiYeH         }
186*52da9a59SGnoCiYeH 
187*52da9a59SGnoCiYeH         if opt.contains(TtySetTermiosOpt::TERMIOS_WAIT) {
188*52da9a59SGnoCiYeH             // TODO
189*52da9a59SGnoCiYeH         }
190*52da9a59SGnoCiYeH 
191*52da9a59SGnoCiYeH         self.set_termios_next(tty, tmp_termios)?;
192*52da9a59SGnoCiYeH         Ok(0)
193*52da9a59SGnoCiYeH     }
194*52da9a59SGnoCiYeH 
195*52da9a59SGnoCiYeH     pub fn set_termios_next(
196*52da9a59SGnoCiYeH         &self,
197*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
198*52da9a59SGnoCiYeH         new_termios: Termios,
199*52da9a59SGnoCiYeH     ) -> Result<(), SystemError> {
200*52da9a59SGnoCiYeH         let mut termios = self.core().termios_write();
201*52da9a59SGnoCiYeH 
202*52da9a59SGnoCiYeH         let old_termios = termios.clone();
203*52da9a59SGnoCiYeH 
204*52da9a59SGnoCiYeH         *termios = new_termios;
205*52da9a59SGnoCiYeH 
206*52da9a59SGnoCiYeH         let tmp = termios.control_mode;
207*52da9a59SGnoCiYeH         termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB;
208*52da9a59SGnoCiYeH 
209*52da9a59SGnoCiYeH         let ret = self.set_termios(tty.clone(), old_termios);
210*52da9a59SGnoCiYeH         if ret.is_err() {
211*52da9a59SGnoCiYeH             termios.control_mode &= ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL;
212*52da9a59SGnoCiYeH             termios.control_mode |= old_termios.control_mode
213*52da9a59SGnoCiYeH                 & !(ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL);
214*52da9a59SGnoCiYeH             termios.input_speed = old_termios.input_speed;
215*52da9a59SGnoCiYeH             termios.output_speed = old_termios.output_speed;
216*52da9a59SGnoCiYeH         }
217*52da9a59SGnoCiYeH 
218*52da9a59SGnoCiYeH         drop(termios);
219*52da9a59SGnoCiYeH         let ld = self.ldisc();
220*52da9a59SGnoCiYeH         ld.set_termios(tty, Some(old_termios))?;
221*52da9a59SGnoCiYeH 
222*52da9a59SGnoCiYeH         Ok(())
223*52da9a59SGnoCiYeH     }
224*52da9a59SGnoCiYeH }
225*52da9a59SGnoCiYeH 
226*52da9a59SGnoCiYeH #[derive(Debug)]
227*52da9a59SGnoCiYeH pub struct TtyContorlInfo {
228*52da9a59SGnoCiYeH     /// 前台进程pid
229*52da9a59SGnoCiYeH     pub session: Option<Pid>,
230*52da9a59SGnoCiYeH     /// 前台进程组id
231*52da9a59SGnoCiYeH     pub pgid: Option<Pid>,
232*52da9a59SGnoCiYeH 
233*52da9a59SGnoCiYeH     /// packet模式下使用,目前未用到
234*52da9a59SGnoCiYeH     pub pktstatus: u8,
235*52da9a59SGnoCiYeH     pub packet: bool,
236*52da9a59SGnoCiYeH }
237*52da9a59SGnoCiYeH 
238*52da9a59SGnoCiYeH impl Default for TtyContorlInfo {
239*52da9a59SGnoCiYeH     fn default() -> Self {
240*52da9a59SGnoCiYeH         Self {
241*52da9a59SGnoCiYeH             session: None,
242*52da9a59SGnoCiYeH             pgid: None,
243*52da9a59SGnoCiYeH             pktstatus: Default::default(),
244*52da9a59SGnoCiYeH             packet: Default::default(),
245*52da9a59SGnoCiYeH         }
246*52da9a59SGnoCiYeH     }
247*52da9a59SGnoCiYeH }
248*52da9a59SGnoCiYeH 
249*52da9a59SGnoCiYeH #[derive(Debug, Default)]
250*52da9a59SGnoCiYeH pub struct TtyCoreWriteData {
251*52da9a59SGnoCiYeH     /// 写缓冲区
252*52da9a59SGnoCiYeH     pub write_buf: Vec<u8>,
253*52da9a59SGnoCiYeH     /// 写入数量
254*52da9a59SGnoCiYeH     pub write_cnt: usize,
255*52da9a59SGnoCiYeH }
256*52da9a59SGnoCiYeH 
257*52da9a59SGnoCiYeH #[derive(Debug, Default)]
258*52da9a59SGnoCiYeH pub struct TtyFlowState {
259*52da9a59SGnoCiYeH     /// 表示流控是否被停止
260*52da9a59SGnoCiYeH     pub stopped: bool,
261*52da9a59SGnoCiYeH     /// 表示 TCO(Transmit Continuous Operation)流控是否被停止
262*52da9a59SGnoCiYeH     pub tco_stopped: bool,
263*52da9a59SGnoCiYeH }
264*52da9a59SGnoCiYeH 
265*52da9a59SGnoCiYeH #[derive(Debug)]
266*52da9a59SGnoCiYeH pub struct TtyCoreData {
267*52da9a59SGnoCiYeH     tty_driver: Arc<TtyDriver>,
268*52da9a59SGnoCiYeH     termios: RwLock<Termios>,
269*52da9a59SGnoCiYeH     name: String,
270*52da9a59SGnoCiYeH     flags: RwLock<TtyFlag>,
271*52da9a59SGnoCiYeH     /// 在初始化时即确定不会更改,所以这里不用加锁
272*52da9a59SGnoCiYeH     index: usize,
273*52da9a59SGnoCiYeH     count: RwLock<usize>,
274*52da9a59SGnoCiYeH     /// 窗口大小
275*52da9a59SGnoCiYeH     window_size: RwLock<WindowSize>,
276*52da9a59SGnoCiYeH     /// 读等待队列
277*52da9a59SGnoCiYeH     read_wq: EventWaitQueue,
278*52da9a59SGnoCiYeH     /// 写等待队列
279*52da9a59SGnoCiYeH     write_wq: EventWaitQueue,
280*52da9a59SGnoCiYeH     /// 端口
281*52da9a59SGnoCiYeH     port: RwLock<Option<Arc<dyn TtyPort>>>,
282*52da9a59SGnoCiYeH     /// 前台进程
283*52da9a59SGnoCiYeH     ctrl: SpinLock<TtyContorlInfo>,
284*52da9a59SGnoCiYeH     /// 是否正在关闭
285*52da9a59SGnoCiYeH     closing: AtomicBool,
286*52da9a59SGnoCiYeH     /// 流控状态
287*52da9a59SGnoCiYeH     flow: SpinLock<TtyFlowState>,
288*52da9a59SGnoCiYeH }
289*52da9a59SGnoCiYeH 
290*52da9a59SGnoCiYeH impl TtyCoreData {
291*52da9a59SGnoCiYeH     #[inline]
292*52da9a59SGnoCiYeH     pub fn driver(&self) -> Arc<TtyDriver> {
293*52da9a59SGnoCiYeH         self.tty_driver.clone()
294*52da9a59SGnoCiYeH     }
295*52da9a59SGnoCiYeH 
296*52da9a59SGnoCiYeH     #[inline]
297*52da9a59SGnoCiYeH     pub fn flow_irqsave(&self) -> SpinLockGuard<TtyFlowState> {
298*52da9a59SGnoCiYeH         self.flow.lock_irqsave()
299*52da9a59SGnoCiYeH     }
300*52da9a59SGnoCiYeH 
301*52da9a59SGnoCiYeH     #[inline]
302*52da9a59SGnoCiYeH     pub fn port(&self) -> Option<Arc<dyn TtyPort>> {
303*52da9a59SGnoCiYeH         self.port.read().clone()
304*52da9a59SGnoCiYeH     }
305*52da9a59SGnoCiYeH 
306*52da9a59SGnoCiYeH     #[inline]
307*52da9a59SGnoCiYeH     pub fn index(&self) -> usize {
308*52da9a59SGnoCiYeH         self.index
309*52da9a59SGnoCiYeH     }
310*52da9a59SGnoCiYeH 
311*52da9a59SGnoCiYeH     #[inline]
312*52da9a59SGnoCiYeH     pub fn name(&self) -> String {
313*52da9a59SGnoCiYeH         self.name.clone()
314*52da9a59SGnoCiYeH     }
315*52da9a59SGnoCiYeH 
316*52da9a59SGnoCiYeH     #[inline]
317*52da9a59SGnoCiYeH     pub fn flags(&self) -> TtyFlag {
318*52da9a59SGnoCiYeH         self.flags.read().clone()
319*52da9a59SGnoCiYeH     }
320*52da9a59SGnoCiYeH 
321*52da9a59SGnoCiYeH     #[inline]
322*52da9a59SGnoCiYeH     pub fn termios(&self) -> RwLockReadGuard<'_, Termios> {
323*52da9a59SGnoCiYeH         self.termios.read()
324*52da9a59SGnoCiYeH     }
325*52da9a59SGnoCiYeH 
326*52da9a59SGnoCiYeH     #[inline]
327*52da9a59SGnoCiYeH     pub fn termios_write(&self) -> RwLockWriteGuard<Termios> {
328*52da9a59SGnoCiYeH         self.termios.write()
329*52da9a59SGnoCiYeH     }
330*52da9a59SGnoCiYeH 
331*52da9a59SGnoCiYeH     #[inline]
332*52da9a59SGnoCiYeH     pub fn set_termios(&self, termios: Termios) {
333*52da9a59SGnoCiYeH         let mut termios_guard = self.termios.write();
334*52da9a59SGnoCiYeH         *termios_guard = termios;
335*52da9a59SGnoCiYeH     }
336*52da9a59SGnoCiYeH 
337*52da9a59SGnoCiYeH     #[inline]
338*52da9a59SGnoCiYeH     pub fn add_count(&self) {
339*52da9a59SGnoCiYeH         let mut guard = self.count.write();
340*52da9a59SGnoCiYeH         *guard += 1;
341*52da9a59SGnoCiYeH     }
342*52da9a59SGnoCiYeH 
343*52da9a59SGnoCiYeH     #[inline]
344*52da9a59SGnoCiYeH     pub fn read_wq(&self) -> &EventWaitQueue {
345*52da9a59SGnoCiYeH         &self.read_wq
346*52da9a59SGnoCiYeH     }
347*52da9a59SGnoCiYeH 
348*52da9a59SGnoCiYeH     #[inline]
349*52da9a59SGnoCiYeH     pub fn write_wq(&self) -> &EventWaitQueue {
350*52da9a59SGnoCiYeH         &self.write_wq
351*52da9a59SGnoCiYeH     }
352*52da9a59SGnoCiYeH 
353*52da9a59SGnoCiYeH     #[inline]
354*52da9a59SGnoCiYeH     pub fn contorl_info_irqsave(&self) -> SpinLockGuard<TtyContorlInfo> {
355*52da9a59SGnoCiYeH         self.ctrl.lock_irqsave()
356*52da9a59SGnoCiYeH     }
357*52da9a59SGnoCiYeH 
358*52da9a59SGnoCiYeH     #[inline]
359*52da9a59SGnoCiYeH     pub fn window_size_upgradeable(&self) -> RwLockUpgradableGuard<WindowSize> {
360*52da9a59SGnoCiYeH         self.window_size.upgradeable_read()
361*52da9a59SGnoCiYeH     }
362*52da9a59SGnoCiYeH 
363*52da9a59SGnoCiYeH     #[inline]
364*52da9a59SGnoCiYeH     pub fn window_size(&self) -> RwLockReadGuard<WindowSize> {
365*52da9a59SGnoCiYeH         self.window_size.read()
366*52da9a59SGnoCiYeH     }
367*52da9a59SGnoCiYeH 
368*52da9a59SGnoCiYeH     #[inline]
369*52da9a59SGnoCiYeH     pub fn is_closing(&self) -> bool {
370*52da9a59SGnoCiYeH         self.closing.load(core::sync::atomic::Ordering::SeqCst)
371*52da9a59SGnoCiYeH     }
372*52da9a59SGnoCiYeH 
373*52da9a59SGnoCiYeH     #[inline]
374*52da9a59SGnoCiYeH     pub fn vc_data_irqsave(&self) -> SpinLockGuard<VirtualConsoleData> {
375*52da9a59SGnoCiYeH         VIRT_CONSOLES[self.index].lock_irqsave()
376*52da9a59SGnoCiYeH     }
377*52da9a59SGnoCiYeH }
378*52da9a59SGnoCiYeH 
379*52da9a59SGnoCiYeH /// TTY 核心接口,不同的tty需要各自实现这个trait
380*52da9a59SGnoCiYeH pub trait TtyCoreFuncs: Debug + Send + Sync {}
381*52da9a59SGnoCiYeH 
382*52da9a59SGnoCiYeH impl TtyOperation for TtyCore {
383*52da9a59SGnoCiYeH     #[inline]
384*52da9a59SGnoCiYeH     fn open(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
385*52da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().open(tty);
386*52da9a59SGnoCiYeH     }
387*52da9a59SGnoCiYeH 
388*52da9a59SGnoCiYeH     #[inline]
389*52da9a59SGnoCiYeH     fn write_room(&self, tty: &TtyCoreData) -> usize {
390*52da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().write_room(tty);
391*52da9a59SGnoCiYeH     }
392*52da9a59SGnoCiYeH 
393*52da9a59SGnoCiYeH     #[inline]
394*52da9a59SGnoCiYeH     fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
395*52da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().write(tty, buf, nr);
396*52da9a59SGnoCiYeH     }
397*52da9a59SGnoCiYeH 
398*52da9a59SGnoCiYeH     #[inline]
399*52da9a59SGnoCiYeH     fn flush_chars(&self, tty: &TtyCoreData) {
400*52da9a59SGnoCiYeH         self.core().tty_driver.driver_funcs().flush_chars(tty);
401*52da9a59SGnoCiYeH     }
402*52da9a59SGnoCiYeH 
403*52da9a59SGnoCiYeH     #[inline]
404*52da9a59SGnoCiYeH     fn put_char(&self, tty: &TtyCoreData, ch: u8) -> Result<(), SystemError> {
405*52da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().put_char(tty, ch);
406*52da9a59SGnoCiYeH     }
407*52da9a59SGnoCiYeH 
408*52da9a59SGnoCiYeH     #[inline]
409*52da9a59SGnoCiYeH     fn install(&self, driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
410*52da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().install(driver, tty);
411*52da9a59SGnoCiYeH     }
412*52da9a59SGnoCiYeH 
413*52da9a59SGnoCiYeH     #[inline]
414*52da9a59SGnoCiYeH     fn start(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
415*52da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().start(tty);
416*52da9a59SGnoCiYeH     }
417*52da9a59SGnoCiYeH 
418*52da9a59SGnoCiYeH     #[inline]
419*52da9a59SGnoCiYeH     fn stop(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
420*52da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().stop(tty);
421*52da9a59SGnoCiYeH     }
422*52da9a59SGnoCiYeH 
423*52da9a59SGnoCiYeH     #[inline]
424*52da9a59SGnoCiYeH     fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError> {
425*52da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().ioctl(tty, cmd, arg);
426*52da9a59SGnoCiYeH     }
427*52da9a59SGnoCiYeH 
428*52da9a59SGnoCiYeH     #[inline]
429*52da9a59SGnoCiYeH     fn chars_in_buffer(&self) -> usize {
430*52da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().chars_in_buffer();
431*52da9a59SGnoCiYeH     }
432*52da9a59SGnoCiYeH 
433*52da9a59SGnoCiYeH     #[inline]
434*52da9a59SGnoCiYeH     fn set_termios(&self, tty: Arc<TtyCore>, old_termios: Termios) -> Result<(), SystemError> {
435*52da9a59SGnoCiYeH         return self
436*52da9a59SGnoCiYeH             .core()
437*52da9a59SGnoCiYeH             .tty_driver
438*52da9a59SGnoCiYeH             .driver_funcs()
439*52da9a59SGnoCiYeH             .set_termios(tty, old_termios);
440*52da9a59SGnoCiYeH     }
441*52da9a59SGnoCiYeH }
442*52da9a59SGnoCiYeH 
443*52da9a59SGnoCiYeH bitflags! {
444*52da9a59SGnoCiYeH     pub struct TtyFlag: u32 {
445*52da9a59SGnoCiYeH         /// 终端被节流
446*52da9a59SGnoCiYeH         const THROTTLED		= 1 << 0;
447*52da9a59SGnoCiYeH         /// 终端输入输出错误状态
448*52da9a59SGnoCiYeH         const IO_ERROR		= 1 << 1;
449*52da9a59SGnoCiYeH         /// 终端的其他一方已关闭
450*52da9a59SGnoCiYeH         const OTHER_CLOSED	= 1 << 2;
451*52da9a59SGnoCiYeH         /// 终端处于独占状态
452*52da9a59SGnoCiYeH         const EXCLUSIVE		= 1 << 3;
453*52da9a59SGnoCiYeH         /// 终端执行写唤醒操作
454*52da9a59SGnoCiYeH         const DO_WRITE_WAKEUP	= 1 << 5;
455*52da9a59SGnoCiYeH         /// 终端线路驱动程序已打开
456*52da9a59SGnoCiYeH         const LDISC_OPEN		= 1 << 11;
457*52da9a59SGnoCiYeH         /// 终端伪终端设备已锁定
458*52da9a59SGnoCiYeH         const PTY_LOCK		= 1 << 16;
459*52da9a59SGnoCiYeH         /// 终端禁用写分裂操作
460*52da9a59SGnoCiYeH         const NO_WRITE_SPLIT	= 1 << 17;
461*52da9a59SGnoCiYeH         /// 终端挂断(挂起)状态
462*52da9a59SGnoCiYeH         const HUPPED		= 1 << 18;
463*52da9a59SGnoCiYeH         /// 终端正在挂断(挂起)
464*52da9a59SGnoCiYeH         const HUPPING		= 1 << 19;
465*52da9a59SGnoCiYeH         /// 终端线路驱动程序正在更改
466*52da9a59SGnoCiYeH         const LDISC_CHANGING	= 1 << 20;
467*52da9a59SGnoCiYeH         /// 终端线路驱动程序已停止
468*52da9a59SGnoCiYeH         const LDISC_HALTED	= 1 << 22;
469*52da9a59SGnoCiYeH     }
470*52da9a59SGnoCiYeH }
471*52da9a59SGnoCiYeH 
472*52da9a59SGnoCiYeH #[derive(Debug, PartialEq)]
473*52da9a59SGnoCiYeH pub enum EchoOperation {
474*52da9a59SGnoCiYeH     /// 开始特殊操作。
475*52da9a59SGnoCiYeH     Start,
476*52da9a59SGnoCiYeH     /// 向后移动光标列。
477*52da9a59SGnoCiYeH     MoveBackCol,
478*52da9a59SGnoCiYeH     /// 设置规范模式下的列位置。
479*52da9a59SGnoCiYeH     SetCanonCol,
480*52da9a59SGnoCiYeH     /// 擦除制表符。
481*52da9a59SGnoCiYeH     EraseTab,
482*52da9a59SGnoCiYeH 
483*52da9a59SGnoCiYeH     Undefined(u8),
484*52da9a59SGnoCiYeH }
485*52da9a59SGnoCiYeH 
486*52da9a59SGnoCiYeH impl EchoOperation {
487*52da9a59SGnoCiYeH     pub fn from_u8(num: u8) -> EchoOperation {
488*52da9a59SGnoCiYeH         match num {
489*52da9a59SGnoCiYeH             0xff => Self::Start,
490*52da9a59SGnoCiYeH             0x80 => Self::MoveBackCol,
491*52da9a59SGnoCiYeH             0x81 => Self::SetCanonCol,
492*52da9a59SGnoCiYeH             0x82 => Self::EraseTab,
493*52da9a59SGnoCiYeH             _ => Self::Undefined(num),
494*52da9a59SGnoCiYeH         }
495*52da9a59SGnoCiYeH     }
496*52da9a59SGnoCiYeH 
497*52da9a59SGnoCiYeH     pub fn to_u8(&self) -> u8 {
498*52da9a59SGnoCiYeH         match *self {
499*52da9a59SGnoCiYeH             EchoOperation::Start => 0xff,
500*52da9a59SGnoCiYeH             EchoOperation::MoveBackCol => 0x80,
501*52da9a59SGnoCiYeH             EchoOperation::SetCanonCol => 0x81,
502*52da9a59SGnoCiYeH             EchoOperation::EraseTab => 0x82,
503*52da9a59SGnoCiYeH             EchoOperation::Undefined(num) => num,
504*52da9a59SGnoCiYeH         }
505*52da9a59SGnoCiYeH     }
506*52da9a59SGnoCiYeH }
507*52da9a59SGnoCiYeH 
508*52da9a59SGnoCiYeH pub struct TtyIoctlCmd;
509*52da9a59SGnoCiYeH 
510*52da9a59SGnoCiYeH #[allow(dead_code)]
511*52da9a59SGnoCiYeH impl TtyIoctlCmd {
512*52da9a59SGnoCiYeH     /// 获取终端参数
513*52da9a59SGnoCiYeH     pub const TCGETS: u32 = 0x5401;
514*52da9a59SGnoCiYeH     /// 设置终端参数
515*52da9a59SGnoCiYeH     pub const TCSETS: u32 = 0x5402;
516*52da9a59SGnoCiYeH     /// 设置终端参数并等待所有输出完成
517*52da9a59SGnoCiYeH     pub const TCSETSW: u32 = 0x5403;
518*52da9a59SGnoCiYeH     /// 设置终端参数并且等待所有输出完成,但在这之前将终端清空
519*52da9a59SGnoCiYeH     pub const TCSETSF: u32 = 0x5404;
520*52da9a59SGnoCiYeH     /// 获取终端参数
521*52da9a59SGnoCiYeH     pub const TCGETA: u32 = 0x5405;
522*52da9a59SGnoCiYeH     /// 设置终端参数
523*52da9a59SGnoCiYeH     pub const TCSETA: u32 = 0x5406;
524*52da9a59SGnoCiYeH     /// 设置终端参数并等待所有输出完成
525*52da9a59SGnoCiYeH     pub const TCSETAW: u32 = 0x5407;
526*52da9a59SGnoCiYeH     /// 设置终端参数并且等待所有输出完成,但在这之前将终端清空
527*52da9a59SGnoCiYeH     pub const TCSETAF: u32 = 0x5408;
528*52da9a59SGnoCiYeH     /// 发送零字节,等待所有输出完成
529*52da9a59SGnoCiYeH     pub const TCSBRK: u32 = 0x5409;
530*52da9a59SGnoCiYeH     /// 控制终端的流控
531*52da9a59SGnoCiYeH     pub const TCXONC: u32 = 0x540A;
532*52da9a59SGnoCiYeH     /// 刷新输入/输出缓冲区或者丢弃输入缓冲区
533*52da9a59SGnoCiYeH     pub const TCFLSH: u32 = 0x540B;
534*52da9a59SGnoCiYeH     /// 设置设备为独占模式
535*52da9a59SGnoCiYeH     pub const TIOCEXCL: u32 = 0x540C;
536*52da9a59SGnoCiYeH     /// 设置设备为非独占模式
537*52da9a59SGnoCiYeH     pub const TIOCNXCL: u32 = 0x540D;
538*52da9a59SGnoCiYeH     /// 设置当前进程的控制终端
539*52da9a59SGnoCiYeH     pub const TIOCSCTTY: u32 = 0x540E;
540*52da9a59SGnoCiYeH     /// 获取前台进程组
541*52da9a59SGnoCiYeH     pub const TIOCGPGRP: u32 = 0x540F;
542*52da9a59SGnoCiYeH     ///设置前台进程组
543*52da9a59SGnoCiYeH     pub const TIOCSPGRP: u32 = 0x5410;
544*52da9a59SGnoCiYeH     /// 获取输出队列的字节数
545*52da9a59SGnoCiYeH     pub const TIOCOUTQ: u32 = 0x5411;
546*52da9a59SGnoCiYeH     /// 模拟从终端输入字符
547*52da9a59SGnoCiYeH     pub const TIOCSTI: u32 = 0x5412;
548*52da9a59SGnoCiYeH     /// 获取窗口大小
549*52da9a59SGnoCiYeH     pub const TIOCGWINSZ: u32 = 0x5413;
550*52da9a59SGnoCiYeH     /// 设置窗口大小
551*52da9a59SGnoCiYeH     pub const TIOCSWINSZ: u32 = 0x5414;
552*52da9a59SGnoCiYeH     /// 获取终端控制信号的状态
553*52da9a59SGnoCiYeH     pub const TIOCMGET: u32 = 0x5415;
554*52da9a59SGnoCiYeH     /// 设置终端控制信号的位
555*52da9a59SGnoCiYeH     pub const TIOCMBIS: u32 = 0x5416;
556*52da9a59SGnoCiYeH     /// 清除终端控制信号的位
557*52da9a59SGnoCiYeH     pub const TIOCMBIC: u32 = 0x5417;
558*52da9a59SGnoCiYeH     /// 设置终端控制信号的状态
559*52da9a59SGnoCiYeH     pub const TIOCMSET: u32 = 0x5418;
560*52da9a59SGnoCiYeH     /// 获取软件载波状态
561*52da9a59SGnoCiYeH     pub const TIOCGSOFTCAR: u32 = 0x5419;
562*52da9a59SGnoCiYeH     /// 设置软件载波状态
563*52da9a59SGnoCiYeH     pub const TIOCSSOFTCAR: u32 = 0x541A;
564*52da9a59SGnoCiYeH     /// 获取输入队列的字节数
565*52da9a59SGnoCiYeH     pub const FIONREAD: u32 = 0x541B;
566*52da9a59SGnoCiYeH     /// Linux 特有命令
567*52da9a59SGnoCiYeH     pub const TIOCLINUX: u32 = 0x541C;
568*52da9a59SGnoCiYeH     /// 获取控制台设备
569*52da9a59SGnoCiYeH     pub const TIOCCONS: u32 = 0x541D;
570*52da9a59SGnoCiYeH     /// 获取串行设备参数
571*52da9a59SGnoCiYeH     pub const TIOCGSERIAL: u32 = 0x541E;
572*52da9a59SGnoCiYeH     /// 设置串行设备参数
573*52da9a59SGnoCiYeH     pub const TIOCSSERIAL: u32 = 0x541F;
574*52da9a59SGnoCiYeH     /// 设置套接字的报文模式
575*52da9a59SGnoCiYeH     pub const TIOCPKT: u32 = 0x5420;
576*52da9a59SGnoCiYeH     /// 设置非阻塞 I/O
577*52da9a59SGnoCiYeH     pub const FIONBIO: u32 = 0x5421;
578*52da9a59SGnoCiYeH     /// 清除控制终端
579*52da9a59SGnoCiYeH     pub const TIOCNOTTY: u32 = 0x5422;
580*52da9a59SGnoCiYeH     /// 设置终端线路驱动器
581*52da9a59SGnoCiYeH     pub const TIOCSETD: u32 = 0x5423;
582*52da9a59SGnoCiYeH     /// 获取终端线路驱动器
583*52da9a59SGnoCiYeH     pub const TIOCGETD: u32 = 0x5424;
584*52da9a59SGnoCiYeH     /// 发送终止条件
585*52da9a59SGnoCiYeH     pub const TCSBRKP: u32 = 0x5425;
586*52da9a59SGnoCiYeH     /// 开始发送零比特
587*52da9a59SGnoCiYeH     pub const TIOCSBRK: u32 = 0x5427;
588*52da9a59SGnoCiYeH     /// 停止发送零比特
589*52da9a59SGnoCiYeH     pub const TIOCCBRK: u32 = 0x5428;
590*52da9a59SGnoCiYeH     /// Return the session ID of FD
591*52da9a59SGnoCiYeH     pub const TIOCGSID: u32 = 0x5429;
592*52da9a59SGnoCiYeH }
593