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