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