xref: /DragonOS/kernel/src/driver/tty/tty_core.rs (revision be60c929c8285d3050e022aa23312a84129e54b2)
152da9a59SGnoCiYeH use core::{fmt::Debug, sync::atomic::AtomicBool};
252da9a59SGnoCiYeH 
352da9a59SGnoCiYeH use alloc::{string::String, sync::Arc, vec::Vec};
452da9a59SGnoCiYeH use system_error::SystemError;
552da9a59SGnoCiYeH 
652da9a59SGnoCiYeH use crate::{
752da9a59SGnoCiYeH     libs::{
852da9a59SGnoCiYeH         rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard},
952da9a59SGnoCiYeH         spinlock::{SpinLock, SpinLockGuard},
1052da9a59SGnoCiYeH         wait_queue::EventWaitQueue,
1152da9a59SGnoCiYeH     },
1252da9a59SGnoCiYeH     mm::VirtAddr,
1352da9a59SGnoCiYeH     net::event_poll::EPollEventType,
1452da9a59SGnoCiYeH     process::Pid,
15*be60c929SGnoCiYeH     syscall::user_access::{UserBufferReader, UserBufferWriter},
1652da9a59SGnoCiYeH };
1752da9a59SGnoCiYeH 
1852da9a59SGnoCiYeH use super::{
1952da9a59SGnoCiYeH     termios::{ControlMode, PosixTermios, Termios, TtySetTermiosOpt, WindowSize},
2052da9a59SGnoCiYeH     tty_driver::{TtyDriver, TtyDriverSubType, TtyDriverType, TtyOperation},
2152da9a59SGnoCiYeH     tty_ldisc::{
2252da9a59SGnoCiYeH         ntty::{NTtyData, NTtyLinediscipline},
2352da9a59SGnoCiYeH         TtyLineDiscipline,
2452da9a59SGnoCiYeH     },
2552da9a59SGnoCiYeH     tty_port::TtyPort,
2652da9a59SGnoCiYeH     virtual_terminal::{virtual_console::VirtualConsoleData, VIRT_CONSOLES},
2752da9a59SGnoCiYeH };
2852da9a59SGnoCiYeH 
2952da9a59SGnoCiYeH #[derive(Debug)]
3052da9a59SGnoCiYeH pub struct TtyCore {
3152da9a59SGnoCiYeH     core: TtyCoreData,
3252da9a59SGnoCiYeH     /// 线路规程函数集
3352da9a59SGnoCiYeH     line_discipline: Arc<dyn TtyLineDiscipline>,
3452da9a59SGnoCiYeH }
3552da9a59SGnoCiYeH 
3652da9a59SGnoCiYeH impl TtyCore {
3752da9a59SGnoCiYeH     pub fn new(driver: Arc<TtyDriver>, index: usize) -> Arc<Self> {
3852da9a59SGnoCiYeH         let name = driver.tty_line_name(index);
3952da9a59SGnoCiYeH         let termios = driver.init_termios();
4052da9a59SGnoCiYeH         let core = TtyCoreData {
4152da9a59SGnoCiYeH             tty_driver: driver,
4252da9a59SGnoCiYeH             termios: RwLock::new(termios),
4352da9a59SGnoCiYeH             name,
4452da9a59SGnoCiYeH             flags: RwLock::new(TtyFlag::empty()),
4552da9a59SGnoCiYeH             count: RwLock::new(0),
4652da9a59SGnoCiYeH             window_size: RwLock::new(WindowSize::default()),
4752da9a59SGnoCiYeH             read_wq: EventWaitQueue::new(),
4852da9a59SGnoCiYeH             write_wq: EventWaitQueue::new(),
4952da9a59SGnoCiYeH             port: RwLock::new(None),
5052da9a59SGnoCiYeH             index,
5152da9a59SGnoCiYeH             ctrl: SpinLock::new(TtyContorlInfo::default()),
5252da9a59SGnoCiYeH             closing: AtomicBool::new(false),
5352da9a59SGnoCiYeH             flow: SpinLock::new(TtyFlowState::default()),
54*be60c929SGnoCiYeH             link: None,
5552da9a59SGnoCiYeH         };
5652da9a59SGnoCiYeH 
5752da9a59SGnoCiYeH         return Arc::new(Self {
5852da9a59SGnoCiYeH             core,
5952da9a59SGnoCiYeH             line_discipline: Arc::new(NTtyLinediscipline {
6052da9a59SGnoCiYeH                 data: SpinLock::new(NTtyData::new()),
6152da9a59SGnoCiYeH             }),
6252da9a59SGnoCiYeH         });
6352da9a59SGnoCiYeH     }
6452da9a59SGnoCiYeH 
6552da9a59SGnoCiYeH     #[inline]
6652da9a59SGnoCiYeH     pub fn core(&self) -> &TtyCoreData {
6752da9a59SGnoCiYeH         return &self.core;
6852da9a59SGnoCiYeH     }
6952da9a59SGnoCiYeH 
7052da9a59SGnoCiYeH     #[inline]
7152da9a59SGnoCiYeH     pub fn ldisc(&self) -> Arc<dyn TtyLineDiscipline> {
7252da9a59SGnoCiYeH         self.line_discipline.clone()
7352da9a59SGnoCiYeH     }
7452da9a59SGnoCiYeH 
7552da9a59SGnoCiYeH     pub fn reopen(&self) -> Result<(), SystemError> {
7652da9a59SGnoCiYeH         let tty_core = self.core();
7752da9a59SGnoCiYeH         let driver = tty_core.driver();
7852da9a59SGnoCiYeH 
7952da9a59SGnoCiYeH         if driver.tty_driver_type() == TtyDriverType::Pty
8052da9a59SGnoCiYeH             && driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster
8152da9a59SGnoCiYeH         {
8252da9a59SGnoCiYeH             return Err(SystemError::EIO);
8352da9a59SGnoCiYeH         }
8452da9a59SGnoCiYeH 
8552da9a59SGnoCiYeH         // if *tty_core.count.read() == 0 {
8652da9a59SGnoCiYeH         //     return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
8752da9a59SGnoCiYeH         // }
8852da9a59SGnoCiYeH 
8952da9a59SGnoCiYeH         // TODO 判断flags
9052da9a59SGnoCiYeH 
9152da9a59SGnoCiYeH         tty_core.add_count();
9252da9a59SGnoCiYeH 
9352da9a59SGnoCiYeH         Ok(())
9452da9a59SGnoCiYeH     }
9552da9a59SGnoCiYeH 
9652da9a59SGnoCiYeH     #[inline]
9752da9a59SGnoCiYeH     pub fn set_port(&self, port: Arc<dyn TtyPort>) {
9852da9a59SGnoCiYeH         *self.core.port.write() = Some(port);
9952da9a59SGnoCiYeH     }
10052da9a59SGnoCiYeH 
10152da9a59SGnoCiYeH     pub fn tty_start(&self) {
10252da9a59SGnoCiYeH         let mut flow = self.core.flow.lock_irqsave();
10352da9a59SGnoCiYeH         if !flow.stopped || flow.tco_stopped {
10452da9a59SGnoCiYeH             return;
10552da9a59SGnoCiYeH         }
10652da9a59SGnoCiYeH 
10752da9a59SGnoCiYeH         flow.stopped = false;
10852da9a59SGnoCiYeH         let _ = self.start(self.core());
10952da9a59SGnoCiYeH         self.tty_wakeup();
11052da9a59SGnoCiYeH     }
11152da9a59SGnoCiYeH 
11252da9a59SGnoCiYeH     pub fn tty_stop(&self) {
11352da9a59SGnoCiYeH         let mut flow = self.core.flow.lock_irqsave();
11452da9a59SGnoCiYeH         if flow.stopped {
11552da9a59SGnoCiYeH             return;
11652da9a59SGnoCiYeH         }
11752da9a59SGnoCiYeH         flow.stopped = true;
11852da9a59SGnoCiYeH 
11952da9a59SGnoCiYeH         let _ = self.stop(self.core());
12052da9a59SGnoCiYeH     }
12152da9a59SGnoCiYeH 
12252da9a59SGnoCiYeH     pub fn tty_wakeup(&self) {
12352da9a59SGnoCiYeH         if self.core.flags.read().contains(TtyFlag::DO_WRITE_WAKEUP) {
12452da9a59SGnoCiYeH             let _ = self.ldisc().write_wakeup(self.core());
12552da9a59SGnoCiYeH         }
12652da9a59SGnoCiYeH 
12752da9a59SGnoCiYeH         self.core()
12852da9a59SGnoCiYeH             .write_wq
12952da9a59SGnoCiYeH             .wakeup(EPollEventType::EPOLLOUT.bits() as u64);
13052da9a59SGnoCiYeH     }
13152da9a59SGnoCiYeH 
132*be60c929SGnoCiYeH     pub fn tty_mode_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> {
133*be60c929SGnoCiYeH         let real_tty;
134*be60c929SGnoCiYeH         let core = tty.core();
135*be60c929SGnoCiYeH         if core.driver().tty_driver_type() == TtyDriverType::Pty
136*be60c929SGnoCiYeH             && core.driver().tty_driver_sub_type() == TtyDriverSubType::PtyMaster
137*be60c929SGnoCiYeH         {
138*be60c929SGnoCiYeH             real_tty = core.link().unwrap();
139*be60c929SGnoCiYeH         } else {
140*be60c929SGnoCiYeH             real_tty = tty;
141*be60c929SGnoCiYeH         }
14252da9a59SGnoCiYeH         match cmd {
14352da9a59SGnoCiYeH             TtyIoctlCmd::TCGETS => {
144*be60c929SGnoCiYeH                 let termios = PosixTermios::from_kernel_termios(real_tty.core.termios().clone());
14552da9a59SGnoCiYeH                 let mut user_writer = UserBufferWriter::new(
14652da9a59SGnoCiYeH                     VirtAddr::new(arg).as_ptr::<PosixTermios>(),
14752da9a59SGnoCiYeH                     core::mem::size_of::<PosixTermios>(),
14852da9a59SGnoCiYeH                     true,
14952da9a59SGnoCiYeH                 )?;
15052da9a59SGnoCiYeH 
15152da9a59SGnoCiYeH                 user_writer.copy_one_to_user(&termios, 0)?;
15252da9a59SGnoCiYeH                 return Ok(0);
15352da9a59SGnoCiYeH             }
15452da9a59SGnoCiYeH             TtyIoctlCmd::TCSETSW => {
155*be60c929SGnoCiYeH                 return TtyCore::core_set_termios(
156*be60c929SGnoCiYeH                     real_tty,
15752da9a59SGnoCiYeH                     VirtAddr::new(arg),
15852da9a59SGnoCiYeH                     TtySetTermiosOpt::TERMIOS_WAIT | TtySetTermiosOpt::TERMIOS_OLD,
15952da9a59SGnoCiYeH                 );
16052da9a59SGnoCiYeH             }
16152da9a59SGnoCiYeH             _ => {
16252da9a59SGnoCiYeH                 return Err(SystemError::ENOIOCTLCMD);
16352da9a59SGnoCiYeH             }
16452da9a59SGnoCiYeH         }
16552da9a59SGnoCiYeH     }
16652da9a59SGnoCiYeH 
16752da9a59SGnoCiYeH     pub fn core_set_termios(
16852da9a59SGnoCiYeH         tty: Arc<TtyCore>,
16952da9a59SGnoCiYeH         arg: VirtAddr,
17052da9a59SGnoCiYeH         opt: TtySetTermiosOpt,
17152da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
172*be60c929SGnoCiYeH         #[allow(unused_assignments)]
173*be60c929SGnoCiYeH         // TERMIOS_TERMIO下会用到
174*be60c929SGnoCiYeH         let mut tmp_termios = tty.core().termios().clone();
17552da9a59SGnoCiYeH 
17652da9a59SGnoCiYeH         if opt.contains(TtySetTermiosOpt::TERMIOS_TERMIO) {
17752da9a59SGnoCiYeH             todo!()
17852da9a59SGnoCiYeH         } else {
179*be60c929SGnoCiYeH             let user_reader = UserBufferReader::new(
18052da9a59SGnoCiYeH                 arg.as_ptr::<PosixTermios>(),
18152da9a59SGnoCiYeH                 core::mem::size_of::<PosixTermios>(),
18252da9a59SGnoCiYeH                 true,
18352da9a59SGnoCiYeH             )?;
18452da9a59SGnoCiYeH 
185*be60c929SGnoCiYeH             let mut term = PosixTermios::default();
186*be60c929SGnoCiYeH             user_reader.copy_one_from_user(&mut term, 0)?;
187*be60c929SGnoCiYeH 
188*be60c929SGnoCiYeH             tmp_termios = term.to_kernel_termios();
18952da9a59SGnoCiYeH         }
19052da9a59SGnoCiYeH 
19152da9a59SGnoCiYeH         if opt.contains(TtySetTermiosOpt::TERMIOS_FLUSH) {
192*be60c929SGnoCiYeH             let ld = tty.ldisc();
19352da9a59SGnoCiYeH             let _ = ld.flush_buffer(tty.clone());
19452da9a59SGnoCiYeH         }
19552da9a59SGnoCiYeH 
19652da9a59SGnoCiYeH         if opt.contains(TtySetTermiosOpt::TERMIOS_WAIT) {
19752da9a59SGnoCiYeH             // TODO
19852da9a59SGnoCiYeH         }
19952da9a59SGnoCiYeH 
200*be60c929SGnoCiYeH         TtyCore::set_termios_next(tty, tmp_termios)?;
20152da9a59SGnoCiYeH         Ok(0)
20252da9a59SGnoCiYeH     }
20352da9a59SGnoCiYeH 
204*be60c929SGnoCiYeH     pub fn set_termios_next(tty: Arc<TtyCore>, new_termios: Termios) -> Result<(), SystemError> {
205*be60c929SGnoCiYeH         let mut termios = tty.core().termios_write();
20652da9a59SGnoCiYeH 
20752da9a59SGnoCiYeH         let old_termios = termios.clone();
20852da9a59SGnoCiYeH 
20952da9a59SGnoCiYeH         *termios = new_termios;
21052da9a59SGnoCiYeH 
21152da9a59SGnoCiYeH         let tmp = termios.control_mode;
21252da9a59SGnoCiYeH         termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB;
21352da9a59SGnoCiYeH 
214*be60c929SGnoCiYeH         let ret = tty.set_termios(tty.clone(), old_termios);
21552da9a59SGnoCiYeH         if ret.is_err() {
21652da9a59SGnoCiYeH             termios.control_mode &= ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL;
21752da9a59SGnoCiYeH             termios.control_mode |= old_termios.control_mode
21852da9a59SGnoCiYeH                 & !(ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL);
21952da9a59SGnoCiYeH             termios.input_speed = old_termios.input_speed;
22052da9a59SGnoCiYeH             termios.output_speed = old_termios.output_speed;
22152da9a59SGnoCiYeH         }
22252da9a59SGnoCiYeH 
22352da9a59SGnoCiYeH         drop(termios);
224*be60c929SGnoCiYeH         let ld = tty.ldisc();
22552da9a59SGnoCiYeH         ld.set_termios(tty, Some(old_termios))?;
22652da9a59SGnoCiYeH 
22752da9a59SGnoCiYeH         Ok(())
22852da9a59SGnoCiYeH     }
22952da9a59SGnoCiYeH }
23052da9a59SGnoCiYeH 
23152da9a59SGnoCiYeH #[derive(Debug)]
23252da9a59SGnoCiYeH pub struct TtyContorlInfo {
23352da9a59SGnoCiYeH     /// 前台进程pid
23452da9a59SGnoCiYeH     pub session: Option<Pid>,
23552da9a59SGnoCiYeH     /// 前台进程组id
23652da9a59SGnoCiYeH     pub pgid: Option<Pid>,
23752da9a59SGnoCiYeH 
23852da9a59SGnoCiYeH     /// packet模式下使用,目前未用到
23952da9a59SGnoCiYeH     pub pktstatus: u8,
24052da9a59SGnoCiYeH     pub packet: bool,
24152da9a59SGnoCiYeH }
24252da9a59SGnoCiYeH 
24352da9a59SGnoCiYeH impl Default for TtyContorlInfo {
24452da9a59SGnoCiYeH     fn default() -> Self {
24552da9a59SGnoCiYeH         Self {
24652da9a59SGnoCiYeH             session: None,
24752da9a59SGnoCiYeH             pgid: None,
24852da9a59SGnoCiYeH             pktstatus: Default::default(),
24952da9a59SGnoCiYeH             packet: Default::default(),
25052da9a59SGnoCiYeH         }
25152da9a59SGnoCiYeH     }
25252da9a59SGnoCiYeH }
25352da9a59SGnoCiYeH 
25452da9a59SGnoCiYeH #[derive(Debug, Default)]
25552da9a59SGnoCiYeH pub struct TtyCoreWriteData {
25652da9a59SGnoCiYeH     /// 写缓冲区
25752da9a59SGnoCiYeH     pub write_buf: Vec<u8>,
25852da9a59SGnoCiYeH     /// 写入数量
25952da9a59SGnoCiYeH     pub write_cnt: usize,
26052da9a59SGnoCiYeH }
26152da9a59SGnoCiYeH 
26252da9a59SGnoCiYeH #[derive(Debug, Default)]
26352da9a59SGnoCiYeH pub struct TtyFlowState {
26452da9a59SGnoCiYeH     /// 表示流控是否被停止
26552da9a59SGnoCiYeH     pub stopped: bool,
26652da9a59SGnoCiYeH     /// 表示 TCO(Transmit Continuous Operation)流控是否被停止
26752da9a59SGnoCiYeH     pub tco_stopped: bool,
26852da9a59SGnoCiYeH }
26952da9a59SGnoCiYeH 
27052da9a59SGnoCiYeH #[derive(Debug)]
27152da9a59SGnoCiYeH pub struct TtyCoreData {
27252da9a59SGnoCiYeH     tty_driver: Arc<TtyDriver>,
27352da9a59SGnoCiYeH     termios: RwLock<Termios>,
27452da9a59SGnoCiYeH     name: String,
27552da9a59SGnoCiYeH     flags: RwLock<TtyFlag>,
27652da9a59SGnoCiYeH     /// 在初始化时即确定不会更改,所以这里不用加锁
27752da9a59SGnoCiYeH     index: usize,
27852da9a59SGnoCiYeH     count: RwLock<usize>,
27952da9a59SGnoCiYeH     /// 窗口大小
28052da9a59SGnoCiYeH     window_size: RwLock<WindowSize>,
28152da9a59SGnoCiYeH     /// 读等待队列
28252da9a59SGnoCiYeH     read_wq: EventWaitQueue,
28352da9a59SGnoCiYeH     /// 写等待队列
28452da9a59SGnoCiYeH     write_wq: EventWaitQueue,
28552da9a59SGnoCiYeH     /// 端口
28652da9a59SGnoCiYeH     port: RwLock<Option<Arc<dyn TtyPort>>>,
28752da9a59SGnoCiYeH     /// 前台进程
28852da9a59SGnoCiYeH     ctrl: SpinLock<TtyContorlInfo>,
28952da9a59SGnoCiYeH     /// 是否正在关闭
29052da9a59SGnoCiYeH     closing: AtomicBool,
29152da9a59SGnoCiYeH     /// 流控状态
29252da9a59SGnoCiYeH     flow: SpinLock<TtyFlowState>,
293*be60c929SGnoCiYeH     /// 链接tty
294*be60c929SGnoCiYeH     link: Option<Arc<TtyCore>>,
29552da9a59SGnoCiYeH }
29652da9a59SGnoCiYeH 
29752da9a59SGnoCiYeH impl TtyCoreData {
29852da9a59SGnoCiYeH     #[inline]
29952da9a59SGnoCiYeH     pub fn driver(&self) -> Arc<TtyDriver> {
30052da9a59SGnoCiYeH         self.tty_driver.clone()
30152da9a59SGnoCiYeH     }
30252da9a59SGnoCiYeH 
30352da9a59SGnoCiYeH     #[inline]
30452da9a59SGnoCiYeH     pub fn flow_irqsave(&self) -> SpinLockGuard<TtyFlowState> {
30552da9a59SGnoCiYeH         self.flow.lock_irqsave()
30652da9a59SGnoCiYeH     }
30752da9a59SGnoCiYeH 
30852da9a59SGnoCiYeH     #[inline]
30952da9a59SGnoCiYeH     pub fn port(&self) -> Option<Arc<dyn TtyPort>> {
31052da9a59SGnoCiYeH         self.port.read().clone()
31152da9a59SGnoCiYeH     }
31252da9a59SGnoCiYeH 
31352da9a59SGnoCiYeH     #[inline]
31452da9a59SGnoCiYeH     pub fn index(&self) -> usize {
31552da9a59SGnoCiYeH         self.index
31652da9a59SGnoCiYeH     }
31752da9a59SGnoCiYeH 
31852da9a59SGnoCiYeH     #[inline]
31952da9a59SGnoCiYeH     pub fn name(&self) -> String {
32052da9a59SGnoCiYeH         self.name.clone()
32152da9a59SGnoCiYeH     }
32252da9a59SGnoCiYeH 
32352da9a59SGnoCiYeH     #[inline]
32452da9a59SGnoCiYeH     pub fn flags(&self) -> TtyFlag {
32552da9a59SGnoCiYeH         self.flags.read().clone()
32652da9a59SGnoCiYeH     }
32752da9a59SGnoCiYeH 
32852da9a59SGnoCiYeH     #[inline]
32952da9a59SGnoCiYeH     pub fn termios(&self) -> RwLockReadGuard<'_, Termios> {
33052da9a59SGnoCiYeH         self.termios.read()
33152da9a59SGnoCiYeH     }
33252da9a59SGnoCiYeH 
33352da9a59SGnoCiYeH     #[inline]
33452da9a59SGnoCiYeH     pub fn termios_write(&self) -> RwLockWriteGuard<Termios> {
33552da9a59SGnoCiYeH         self.termios.write()
33652da9a59SGnoCiYeH     }
33752da9a59SGnoCiYeH 
33852da9a59SGnoCiYeH     #[inline]
33952da9a59SGnoCiYeH     pub fn set_termios(&self, termios: Termios) {
34052da9a59SGnoCiYeH         let mut termios_guard = self.termios.write();
34152da9a59SGnoCiYeH         *termios_guard = termios;
34252da9a59SGnoCiYeH     }
34352da9a59SGnoCiYeH 
34452da9a59SGnoCiYeH     #[inline]
34552da9a59SGnoCiYeH     pub fn add_count(&self) {
34652da9a59SGnoCiYeH         let mut guard = self.count.write();
34752da9a59SGnoCiYeH         *guard += 1;
34852da9a59SGnoCiYeH     }
34952da9a59SGnoCiYeH 
35052da9a59SGnoCiYeH     #[inline]
35152da9a59SGnoCiYeH     pub fn read_wq(&self) -> &EventWaitQueue {
35252da9a59SGnoCiYeH         &self.read_wq
35352da9a59SGnoCiYeH     }
35452da9a59SGnoCiYeH 
35552da9a59SGnoCiYeH     #[inline]
35652da9a59SGnoCiYeH     pub fn write_wq(&self) -> &EventWaitQueue {
35752da9a59SGnoCiYeH         &self.write_wq
35852da9a59SGnoCiYeH     }
35952da9a59SGnoCiYeH 
36052da9a59SGnoCiYeH     #[inline]
36152da9a59SGnoCiYeH     pub fn contorl_info_irqsave(&self) -> SpinLockGuard<TtyContorlInfo> {
36252da9a59SGnoCiYeH         self.ctrl.lock_irqsave()
36352da9a59SGnoCiYeH     }
36452da9a59SGnoCiYeH 
36552da9a59SGnoCiYeH     #[inline]
36652da9a59SGnoCiYeH     pub fn window_size_upgradeable(&self) -> RwLockUpgradableGuard<WindowSize> {
36752da9a59SGnoCiYeH         self.window_size.upgradeable_read()
36852da9a59SGnoCiYeH     }
36952da9a59SGnoCiYeH 
37052da9a59SGnoCiYeH     #[inline]
37152da9a59SGnoCiYeH     pub fn window_size(&self) -> RwLockReadGuard<WindowSize> {
37252da9a59SGnoCiYeH         self.window_size.read()
37352da9a59SGnoCiYeH     }
37452da9a59SGnoCiYeH 
37552da9a59SGnoCiYeH     #[inline]
37652da9a59SGnoCiYeH     pub fn is_closing(&self) -> bool {
37752da9a59SGnoCiYeH         self.closing.load(core::sync::atomic::Ordering::SeqCst)
37852da9a59SGnoCiYeH     }
37952da9a59SGnoCiYeH 
38052da9a59SGnoCiYeH     #[inline]
38152da9a59SGnoCiYeH     pub fn vc_data_irqsave(&self) -> SpinLockGuard<VirtualConsoleData> {
38252da9a59SGnoCiYeH         VIRT_CONSOLES[self.index].lock_irqsave()
38352da9a59SGnoCiYeH     }
384*be60c929SGnoCiYeH 
385*be60c929SGnoCiYeH     #[inline]
386*be60c929SGnoCiYeH     pub fn link(&self) -> Option<Arc<TtyCore>> {
387*be60c929SGnoCiYeH         self.link.clone()
388*be60c929SGnoCiYeH     }
38952da9a59SGnoCiYeH }
39052da9a59SGnoCiYeH 
39152da9a59SGnoCiYeH /// TTY 核心接口,不同的tty需要各自实现这个trait
39252da9a59SGnoCiYeH pub trait TtyCoreFuncs: Debug + Send + Sync {}
39352da9a59SGnoCiYeH 
39452da9a59SGnoCiYeH impl TtyOperation for TtyCore {
39552da9a59SGnoCiYeH     #[inline]
39652da9a59SGnoCiYeH     fn open(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
39752da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().open(tty);
39852da9a59SGnoCiYeH     }
39952da9a59SGnoCiYeH 
40052da9a59SGnoCiYeH     #[inline]
40152da9a59SGnoCiYeH     fn write_room(&self, tty: &TtyCoreData) -> usize {
40252da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().write_room(tty);
40352da9a59SGnoCiYeH     }
40452da9a59SGnoCiYeH 
40552da9a59SGnoCiYeH     #[inline]
40652da9a59SGnoCiYeH     fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> {
40752da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().write(tty, buf, nr);
40852da9a59SGnoCiYeH     }
40952da9a59SGnoCiYeH 
41052da9a59SGnoCiYeH     #[inline]
41152da9a59SGnoCiYeH     fn flush_chars(&self, tty: &TtyCoreData) {
41252da9a59SGnoCiYeH         self.core().tty_driver.driver_funcs().flush_chars(tty);
41352da9a59SGnoCiYeH     }
41452da9a59SGnoCiYeH 
41552da9a59SGnoCiYeH     #[inline]
41652da9a59SGnoCiYeH     fn put_char(&self, tty: &TtyCoreData, ch: u8) -> Result<(), SystemError> {
41752da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().put_char(tty, ch);
41852da9a59SGnoCiYeH     }
41952da9a59SGnoCiYeH 
42052da9a59SGnoCiYeH     #[inline]
42152da9a59SGnoCiYeH     fn install(&self, driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
42252da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().install(driver, tty);
42352da9a59SGnoCiYeH     }
42452da9a59SGnoCiYeH 
42552da9a59SGnoCiYeH     #[inline]
42652da9a59SGnoCiYeH     fn start(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
42752da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().start(tty);
42852da9a59SGnoCiYeH     }
42952da9a59SGnoCiYeH 
43052da9a59SGnoCiYeH     #[inline]
43152da9a59SGnoCiYeH     fn stop(&self, tty: &TtyCoreData) -> Result<(), SystemError> {
43252da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().stop(tty);
43352da9a59SGnoCiYeH     }
43452da9a59SGnoCiYeH 
43552da9a59SGnoCiYeH     #[inline]
43652da9a59SGnoCiYeH     fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError> {
43752da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().ioctl(tty, cmd, arg);
43852da9a59SGnoCiYeH     }
43952da9a59SGnoCiYeH 
44052da9a59SGnoCiYeH     #[inline]
44152da9a59SGnoCiYeH     fn chars_in_buffer(&self) -> usize {
44252da9a59SGnoCiYeH         return self.core().tty_driver.driver_funcs().chars_in_buffer();
44352da9a59SGnoCiYeH     }
44452da9a59SGnoCiYeH 
44552da9a59SGnoCiYeH     #[inline]
44652da9a59SGnoCiYeH     fn set_termios(&self, tty: Arc<TtyCore>, old_termios: Termios) -> Result<(), SystemError> {
44752da9a59SGnoCiYeH         return self
44852da9a59SGnoCiYeH             .core()
44952da9a59SGnoCiYeH             .tty_driver
45052da9a59SGnoCiYeH             .driver_funcs()
45152da9a59SGnoCiYeH             .set_termios(tty, old_termios);
45252da9a59SGnoCiYeH     }
45352da9a59SGnoCiYeH }
45452da9a59SGnoCiYeH 
45552da9a59SGnoCiYeH bitflags! {
45652da9a59SGnoCiYeH     pub struct TtyFlag: u32 {
45752da9a59SGnoCiYeH         /// 终端被节流
45852da9a59SGnoCiYeH         const THROTTLED		= 1 << 0;
45952da9a59SGnoCiYeH         /// 终端输入输出错误状态
46052da9a59SGnoCiYeH         const IO_ERROR		= 1 << 1;
46152da9a59SGnoCiYeH         /// 终端的其他一方已关闭
46252da9a59SGnoCiYeH         const OTHER_CLOSED	= 1 << 2;
46352da9a59SGnoCiYeH         /// 终端处于独占状态
46452da9a59SGnoCiYeH         const EXCLUSIVE		= 1 << 3;
46552da9a59SGnoCiYeH         /// 终端执行写唤醒操作
46652da9a59SGnoCiYeH         const DO_WRITE_WAKEUP	= 1 << 5;
46752da9a59SGnoCiYeH         /// 终端线路驱动程序已打开
46852da9a59SGnoCiYeH         const LDISC_OPEN		= 1 << 11;
46952da9a59SGnoCiYeH         /// 终端伪终端设备已锁定
47052da9a59SGnoCiYeH         const PTY_LOCK		= 1 << 16;
47152da9a59SGnoCiYeH         /// 终端禁用写分裂操作
47252da9a59SGnoCiYeH         const NO_WRITE_SPLIT	= 1 << 17;
47352da9a59SGnoCiYeH         /// 终端挂断(挂起)状态
47452da9a59SGnoCiYeH         const HUPPED		= 1 << 18;
47552da9a59SGnoCiYeH         /// 终端正在挂断(挂起)
47652da9a59SGnoCiYeH         const HUPPING		= 1 << 19;
47752da9a59SGnoCiYeH         /// 终端线路驱动程序正在更改
47852da9a59SGnoCiYeH         const LDISC_CHANGING	= 1 << 20;
47952da9a59SGnoCiYeH         /// 终端线路驱动程序已停止
48052da9a59SGnoCiYeH         const LDISC_HALTED	= 1 << 22;
48152da9a59SGnoCiYeH     }
48252da9a59SGnoCiYeH }
48352da9a59SGnoCiYeH 
48452da9a59SGnoCiYeH #[derive(Debug, PartialEq)]
48552da9a59SGnoCiYeH pub enum EchoOperation {
48652da9a59SGnoCiYeH     /// 开始特殊操作。
48752da9a59SGnoCiYeH     Start,
48852da9a59SGnoCiYeH     /// 向后移动光标列。
48952da9a59SGnoCiYeH     MoveBackCol,
49052da9a59SGnoCiYeH     /// 设置规范模式下的列位置。
49152da9a59SGnoCiYeH     SetCanonCol,
49252da9a59SGnoCiYeH     /// 擦除制表符。
49352da9a59SGnoCiYeH     EraseTab,
49452da9a59SGnoCiYeH 
49552da9a59SGnoCiYeH     Undefined(u8),
49652da9a59SGnoCiYeH }
49752da9a59SGnoCiYeH 
49852da9a59SGnoCiYeH impl EchoOperation {
49952da9a59SGnoCiYeH     pub fn from_u8(num: u8) -> EchoOperation {
50052da9a59SGnoCiYeH         match num {
50152da9a59SGnoCiYeH             0xff => Self::Start,
50252da9a59SGnoCiYeH             0x80 => Self::MoveBackCol,
50352da9a59SGnoCiYeH             0x81 => Self::SetCanonCol,
50452da9a59SGnoCiYeH             0x82 => Self::EraseTab,
50552da9a59SGnoCiYeH             _ => Self::Undefined(num),
50652da9a59SGnoCiYeH         }
50752da9a59SGnoCiYeH     }
50852da9a59SGnoCiYeH 
50952da9a59SGnoCiYeH     pub fn to_u8(&self) -> u8 {
51052da9a59SGnoCiYeH         match *self {
51152da9a59SGnoCiYeH             EchoOperation::Start => 0xff,
51252da9a59SGnoCiYeH             EchoOperation::MoveBackCol => 0x80,
51352da9a59SGnoCiYeH             EchoOperation::SetCanonCol => 0x81,
51452da9a59SGnoCiYeH             EchoOperation::EraseTab => 0x82,
51552da9a59SGnoCiYeH             EchoOperation::Undefined(num) => num,
51652da9a59SGnoCiYeH         }
51752da9a59SGnoCiYeH     }
51852da9a59SGnoCiYeH }
51952da9a59SGnoCiYeH 
52052da9a59SGnoCiYeH pub struct TtyIoctlCmd;
52152da9a59SGnoCiYeH 
52252da9a59SGnoCiYeH #[allow(dead_code)]
52352da9a59SGnoCiYeH impl TtyIoctlCmd {
52452da9a59SGnoCiYeH     /// 获取终端参数
52552da9a59SGnoCiYeH     pub const TCGETS: u32 = 0x5401;
52652da9a59SGnoCiYeH     /// 设置终端参数
52752da9a59SGnoCiYeH     pub const TCSETS: u32 = 0x5402;
52852da9a59SGnoCiYeH     /// 设置终端参数并等待所有输出完成
52952da9a59SGnoCiYeH     pub const TCSETSW: u32 = 0x5403;
53052da9a59SGnoCiYeH     /// 设置终端参数并且等待所有输出完成,但在这之前将终端清空
53152da9a59SGnoCiYeH     pub const TCSETSF: u32 = 0x5404;
53252da9a59SGnoCiYeH     /// 获取终端参数
53352da9a59SGnoCiYeH     pub const TCGETA: u32 = 0x5405;
53452da9a59SGnoCiYeH     /// 设置终端参数
53552da9a59SGnoCiYeH     pub const TCSETA: u32 = 0x5406;
53652da9a59SGnoCiYeH     /// 设置终端参数并等待所有输出完成
53752da9a59SGnoCiYeH     pub const TCSETAW: u32 = 0x5407;
53852da9a59SGnoCiYeH     /// 设置终端参数并且等待所有输出完成,但在这之前将终端清空
53952da9a59SGnoCiYeH     pub const TCSETAF: u32 = 0x5408;
54052da9a59SGnoCiYeH     /// 发送零字节,等待所有输出完成
54152da9a59SGnoCiYeH     pub const TCSBRK: u32 = 0x5409;
54252da9a59SGnoCiYeH     /// 控制终端的流控
54352da9a59SGnoCiYeH     pub const TCXONC: u32 = 0x540A;
54452da9a59SGnoCiYeH     /// 刷新输入/输出缓冲区或者丢弃输入缓冲区
54552da9a59SGnoCiYeH     pub const TCFLSH: u32 = 0x540B;
54652da9a59SGnoCiYeH     /// 设置设备为独占模式
54752da9a59SGnoCiYeH     pub const TIOCEXCL: u32 = 0x540C;
54852da9a59SGnoCiYeH     /// 设置设备为非独占模式
54952da9a59SGnoCiYeH     pub const TIOCNXCL: u32 = 0x540D;
55052da9a59SGnoCiYeH     /// 设置当前进程的控制终端
55152da9a59SGnoCiYeH     pub const TIOCSCTTY: u32 = 0x540E;
55252da9a59SGnoCiYeH     /// 获取前台进程组
55352da9a59SGnoCiYeH     pub const TIOCGPGRP: u32 = 0x540F;
55452da9a59SGnoCiYeH     ///设置前台进程组
55552da9a59SGnoCiYeH     pub const TIOCSPGRP: u32 = 0x5410;
55652da9a59SGnoCiYeH     /// 获取输出队列的字节数
55752da9a59SGnoCiYeH     pub const TIOCOUTQ: u32 = 0x5411;
55852da9a59SGnoCiYeH     /// 模拟从终端输入字符
55952da9a59SGnoCiYeH     pub const TIOCSTI: u32 = 0x5412;
56052da9a59SGnoCiYeH     /// 获取窗口大小
56152da9a59SGnoCiYeH     pub const TIOCGWINSZ: u32 = 0x5413;
56252da9a59SGnoCiYeH     /// 设置窗口大小
56352da9a59SGnoCiYeH     pub const TIOCSWINSZ: u32 = 0x5414;
56452da9a59SGnoCiYeH     /// 获取终端控制信号的状态
56552da9a59SGnoCiYeH     pub const TIOCMGET: u32 = 0x5415;
56652da9a59SGnoCiYeH     /// 设置终端控制信号的位
56752da9a59SGnoCiYeH     pub const TIOCMBIS: u32 = 0x5416;
56852da9a59SGnoCiYeH     /// 清除终端控制信号的位
56952da9a59SGnoCiYeH     pub const TIOCMBIC: u32 = 0x5417;
57052da9a59SGnoCiYeH     /// 设置终端控制信号的状态
57152da9a59SGnoCiYeH     pub const TIOCMSET: u32 = 0x5418;
57252da9a59SGnoCiYeH     /// 获取软件载波状态
57352da9a59SGnoCiYeH     pub const TIOCGSOFTCAR: u32 = 0x5419;
57452da9a59SGnoCiYeH     /// 设置软件载波状态
57552da9a59SGnoCiYeH     pub const TIOCSSOFTCAR: u32 = 0x541A;
57652da9a59SGnoCiYeH     /// 获取输入队列的字节数
57752da9a59SGnoCiYeH     pub const FIONREAD: u32 = 0x541B;
57852da9a59SGnoCiYeH     /// Linux 特有命令
57952da9a59SGnoCiYeH     pub const TIOCLINUX: u32 = 0x541C;
58052da9a59SGnoCiYeH     /// 获取控制台设备
58152da9a59SGnoCiYeH     pub const TIOCCONS: u32 = 0x541D;
58252da9a59SGnoCiYeH     /// 获取串行设备参数
58352da9a59SGnoCiYeH     pub const TIOCGSERIAL: u32 = 0x541E;
58452da9a59SGnoCiYeH     /// 设置串行设备参数
58552da9a59SGnoCiYeH     pub const TIOCSSERIAL: u32 = 0x541F;
58652da9a59SGnoCiYeH     /// 设置套接字的报文模式
58752da9a59SGnoCiYeH     pub const TIOCPKT: u32 = 0x5420;
58852da9a59SGnoCiYeH     /// 设置非阻塞 I/O
58952da9a59SGnoCiYeH     pub const FIONBIO: u32 = 0x5421;
59052da9a59SGnoCiYeH     /// 清除控制终端
59152da9a59SGnoCiYeH     pub const TIOCNOTTY: u32 = 0x5422;
59252da9a59SGnoCiYeH     /// 设置终端线路驱动器
59352da9a59SGnoCiYeH     pub const TIOCSETD: u32 = 0x5423;
59452da9a59SGnoCiYeH     /// 获取终端线路驱动器
59552da9a59SGnoCiYeH     pub const TIOCGETD: u32 = 0x5424;
59652da9a59SGnoCiYeH     /// 发送终止条件
59752da9a59SGnoCiYeH     pub const TCSBRKP: u32 = 0x5425;
59852da9a59SGnoCiYeH     /// 开始发送零比特
59952da9a59SGnoCiYeH     pub const TIOCSBRK: u32 = 0x5427;
60052da9a59SGnoCiYeH     /// 停止发送零比特
60152da9a59SGnoCiYeH     pub const TIOCCBRK: u32 = 0x5428;
60252da9a59SGnoCiYeH     /// Return the session ID of FD
60352da9a59SGnoCiYeH     pub const TIOCGSID: u32 = 0x5429;
60452da9a59SGnoCiYeH }
605