159fdb447SLoGin use core::{ 259fdb447SLoGin fmt::Debug, 3dfe53cf0SGnoCiYeH sync::atomic::{AtomicBool, AtomicUsize, Ordering}, 459fdb447SLoGin }; 552da9a59SGnoCiYeH 6dfe53cf0SGnoCiYeH use alloc::{ 7dfe53cf0SGnoCiYeH collections::LinkedList, 8dfe53cf0SGnoCiYeH string::String, 9dfe53cf0SGnoCiYeH sync::{Arc, Weak}, 10dfe53cf0SGnoCiYeH }; 1152da9a59SGnoCiYeH use system_error::SystemError; 1252da9a59SGnoCiYeH 1352da9a59SGnoCiYeH use crate::{ 14*9365e801SGnoCiYeH driver::{serial::serial8250::send_to_default_serial8250_port, tty::pty::ptm_driver}, 1552da9a59SGnoCiYeH libs::{ 1652da9a59SGnoCiYeH rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard}, 1752da9a59SGnoCiYeH spinlock::{SpinLock, SpinLockGuard}, 1852da9a59SGnoCiYeH wait_queue::EventWaitQueue, 1952da9a59SGnoCiYeH }, 2052da9a59SGnoCiYeH mm::VirtAddr, 2152bcb59eSGnoCiYeH net::event_poll::{EPollEventType, EPollItem}, 2252da9a59SGnoCiYeH process::Pid, 23be60c929SGnoCiYeH syscall::user_access::{UserBufferReader, UserBufferWriter}, 2452da9a59SGnoCiYeH }; 2552da9a59SGnoCiYeH 2652da9a59SGnoCiYeH use super::{ 2752da9a59SGnoCiYeH termios::{ControlMode, PosixTermios, Termios, TtySetTermiosOpt, WindowSize}, 2852da9a59SGnoCiYeH tty_driver::{TtyDriver, TtyDriverSubType, TtyDriverType, TtyOperation}, 2952da9a59SGnoCiYeH tty_ldisc::{ 3052da9a59SGnoCiYeH ntty::{NTtyData, NTtyLinediscipline}, 3152da9a59SGnoCiYeH TtyLineDiscipline, 3252da9a59SGnoCiYeH }, 3352da9a59SGnoCiYeH tty_port::TtyPort, 3452da9a59SGnoCiYeH virtual_terminal::{virtual_console::VirtualConsoleData, VIRT_CONSOLES}, 3552da9a59SGnoCiYeH }; 3652da9a59SGnoCiYeH 3752da9a59SGnoCiYeH #[derive(Debug)] 3852da9a59SGnoCiYeH pub struct TtyCore { 3952da9a59SGnoCiYeH core: TtyCoreData, 4052da9a59SGnoCiYeH /// 线路规程函数集 4152da9a59SGnoCiYeH line_discipline: Arc<dyn TtyLineDiscipline>, 4252da9a59SGnoCiYeH } 4352da9a59SGnoCiYeH 44*9365e801SGnoCiYeH impl Drop for TtyCore { drop(&mut self)45*9365e801SGnoCiYeH fn drop(&mut self) { 46*9365e801SGnoCiYeH if self.core.driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave { 47*9365e801SGnoCiYeH ptm_driver().ttys().remove(&self.core().index); 48*9365e801SGnoCiYeH } 49*9365e801SGnoCiYeH } 50*9365e801SGnoCiYeH } 51*9365e801SGnoCiYeH 5252da9a59SGnoCiYeH impl TtyCore { new(driver: Arc<TtyDriver>, index: usize) -> Arc<Self>5352da9a59SGnoCiYeH pub fn new(driver: Arc<TtyDriver>, index: usize) -> Arc<Self> { 5452da9a59SGnoCiYeH let name = driver.tty_line_name(index); 5552da9a59SGnoCiYeH let termios = driver.init_termios(); 5652da9a59SGnoCiYeH let core = TtyCoreData { 5752da9a59SGnoCiYeH tty_driver: driver, 5852da9a59SGnoCiYeH termios: RwLock::new(termios), 5952da9a59SGnoCiYeH name, 6052da9a59SGnoCiYeH flags: RwLock::new(TtyFlag::empty()), 6159fdb447SLoGin count: AtomicUsize::new(0), 6252da9a59SGnoCiYeH window_size: RwLock::new(WindowSize::default()), 6352da9a59SGnoCiYeH read_wq: EventWaitQueue::new(), 6452da9a59SGnoCiYeH write_wq: EventWaitQueue::new(), 6552da9a59SGnoCiYeH port: RwLock::new(None), 6652da9a59SGnoCiYeH index, 6752da9a59SGnoCiYeH ctrl: SpinLock::new(TtyContorlInfo::default()), 6852da9a59SGnoCiYeH closing: AtomicBool::new(false), 6952da9a59SGnoCiYeH flow: SpinLock::new(TtyFlowState::default()), 70dfe53cf0SGnoCiYeH link: RwLock::default(), 7152bcb59eSGnoCiYeH epitems: SpinLock::new(LinkedList::new()), 7252da9a59SGnoCiYeH }; 7352da9a59SGnoCiYeH 7452da9a59SGnoCiYeH return Arc::new(Self { 7552da9a59SGnoCiYeH core, 7652da9a59SGnoCiYeH line_discipline: Arc::new(NTtyLinediscipline { 7752da9a59SGnoCiYeH data: SpinLock::new(NTtyData::new()), 7852da9a59SGnoCiYeH }), 7952da9a59SGnoCiYeH }); 8052da9a59SGnoCiYeH } 8152da9a59SGnoCiYeH 8252da9a59SGnoCiYeH #[inline] core(&self) -> &TtyCoreData8352da9a59SGnoCiYeH pub fn core(&self) -> &TtyCoreData { 8452da9a59SGnoCiYeH return &self.core; 8552da9a59SGnoCiYeH } 8652da9a59SGnoCiYeH 8752da9a59SGnoCiYeH #[inline] ldisc(&self) -> Arc<dyn TtyLineDiscipline>8852da9a59SGnoCiYeH pub fn ldisc(&self) -> Arc<dyn TtyLineDiscipline> { 8952da9a59SGnoCiYeH self.line_discipline.clone() 9052da9a59SGnoCiYeH } 9152da9a59SGnoCiYeH write_without_serial(&self, buf: &[u8], nr: usize) -> Result<usize, SystemError>92f3b05a97SGnoCiYeH pub fn write_without_serial(&self, buf: &[u8], nr: usize) -> Result<usize, SystemError> { 93f3b05a97SGnoCiYeH self.core 94f3b05a97SGnoCiYeH .driver() 95f3b05a97SGnoCiYeH .driver_funcs() 96f3b05a97SGnoCiYeH .write(self.core(), buf, nr) 97f3b05a97SGnoCiYeH } 98f3b05a97SGnoCiYeH reopen(&self) -> Result<(), SystemError>9952da9a59SGnoCiYeH pub fn reopen(&self) -> Result<(), SystemError> { 10052da9a59SGnoCiYeH let tty_core = self.core(); 10152da9a59SGnoCiYeH let driver = tty_core.driver(); 10252da9a59SGnoCiYeH 10352da9a59SGnoCiYeH if driver.tty_driver_type() == TtyDriverType::Pty 10452da9a59SGnoCiYeH && driver.tty_driver_sub_type() == TtyDriverSubType::PtyMaster 10552da9a59SGnoCiYeH { 10652da9a59SGnoCiYeH return Err(SystemError::EIO); 10752da9a59SGnoCiYeH } 10852da9a59SGnoCiYeH 10952da9a59SGnoCiYeH // if *tty_core.count.read() == 0 { 11052da9a59SGnoCiYeH // return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 11152da9a59SGnoCiYeH // } 11252da9a59SGnoCiYeH 11352da9a59SGnoCiYeH // TODO 判断flags 11452da9a59SGnoCiYeH 11552da9a59SGnoCiYeH tty_core.add_count(); 11652da9a59SGnoCiYeH 11752da9a59SGnoCiYeH Ok(()) 11852da9a59SGnoCiYeH } 11952da9a59SGnoCiYeH 12052da9a59SGnoCiYeH #[inline] set_port(&self, port: Arc<dyn TtyPort>)12152da9a59SGnoCiYeH pub fn set_port(&self, port: Arc<dyn TtyPort>) { 12252da9a59SGnoCiYeH *self.core.port.write() = Some(port); 12352da9a59SGnoCiYeH } 12452da9a59SGnoCiYeH tty_start(&self)12552da9a59SGnoCiYeH pub fn tty_start(&self) { 12652da9a59SGnoCiYeH let mut flow = self.core.flow.lock_irqsave(); 12752da9a59SGnoCiYeH if !flow.stopped || flow.tco_stopped { 12852da9a59SGnoCiYeH return; 12952da9a59SGnoCiYeH } 13052da9a59SGnoCiYeH 13152da9a59SGnoCiYeH flow.stopped = false; 13252da9a59SGnoCiYeH let _ = self.start(self.core()); 13352da9a59SGnoCiYeH self.tty_wakeup(); 13452da9a59SGnoCiYeH } 13552da9a59SGnoCiYeH tty_stop(&self)13652da9a59SGnoCiYeH pub fn tty_stop(&self) { 13752da9a59SGnoCiYeH let mut flow = self.core.flow.lock_irqsave(); 13852da9a59SGnoCiYeH if flow.stopped { 13952da9a59SGnoCiYeH return; 14052da9a59SGnoCiYeH } 14152da9a59SGnoCiYeH flow.stopped = true; 14252da9a59SGnoCiYeH 14352da9a59SGnoCiYeH let _ = self.stop(self.core()); 14452da9a59SGnoCiYeH } 14552da9a59SGnoCiYeH tty_wakeup(&self)14652da9a59SGnoCiYeH pub fn tty_wakeup(&self) { 14759fdb447SLoGin if self.core.flags().contains(TtyFlag::DO_WRITE_WAKEUP) { 14852da9a59SGnoCiYeH let _ = self.ldisc().write_wakeup(self.core()); 14952da9a59SGnoCiYeH } 15052da9a59SGnoCiYeH 15152da9a59SGnoCiYeH self.core() 15252da9a59SGnoCiYeH .write_wq 153dfe53cf0SGnoCiYeH .wakeup_any(EPollEventType::EPOLLOUT.bits() as u64); 15452da9a59SGnoCiYeH } 15552da9a59SGnoCiYeH tty_mode_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError>156be60c929SGnoCiYeH pub fn tty_mode_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> { 157be60c929SGnoCiYeH let core = tty.core(); 158b5b571e0SLoGin let real_tty = if core.driver().tty_driver_type() == TtyDriverType::Pty 159be60c929SGnoCiYeH && core.driver().tty_driver_sub_type() == TtyDriverSubType::PtyMaster 160be60c929SGnoCiYeH { 161b5b571e0SLoGin core.link().unwrap() 162be60c929SGnoCiYeH } else { 163b5b571e0SLoGin tty 164b5b571e0SLoGin }; 16552da9a59SGnoCiYeH match cmd { 16652da9a59SGnoCiYeH TtyIoctlCmd::TCGETS => { 167b5b571e0SLoGin let termios = PosixTermios::from_kernel_termios(*real_tty.core.termios()); 16852da9a59SGnoCiYeH let mut user_writer = UserBufferWriter::new( 16952da9a59SGnoCiYeH VirtAddr::new(arg).as_ptr::<PosixTermios>(), 17052da9a59SGnoCiYeH core::mem::size_of::<PosixTermios>(), 17152da9a59SGnoCiYeH true, 17252da9a59SGnoCiYeH )?; 17352da9a59SGnoCiYeH 17452da9a59SGnoCiYeH user_writer.copy_one_to_user(&termios, 0)?; 17552da9a59SGnoCiYeH return Ok(0); 17652da9a59SGnoCiYeH } 17752bcb59eSGnoCiYeH TtyIoctlCmd::TCSETS => { 17852bcb59eSGnoCiYeH return TtyCore::core_set_termios( 17952bcb59eSGnoCiYeH real_tty, 18052bcb59eSGnoCiYeH VirtAddr::new(arg), 18152bcb59eSGnoCiYeH TtySetTermiosOpt::TERMIOS_OLD, 18252bcb59eSGnoCiYeH ); 18352bcb59eSGnoCiYeH } 18452da9a59SGnoCiYeH TtyIoctlCmd::TCSETSW => { 185be60c929SGnoCiYeH return TtyCore::core_set_termios( 186be60c929SGnoCiYeH real_tty, 18752da9a59SGnoCiYeH VirtAddr::new(arg), 18852da9a59SGnoCiYeH TtySetTermiosOpt::TERMIOS_WAIT | TtySetTermiosOpt::TERMIOS_OLD, 18952da9a59SGnoCiYeH ); 19052da9a59SGnoCiYeH } 19152da9a59SGnoCiYeH _ => { 19252da9a59SGnoCiYeH return Err(SystemError::ENOIOCTLCMD); 19352da9a59SGnoCiYeH } 19452da9a59SGnoCiYeH } 19552da9a59SGnoCiYeH } 19652da9a59SGnoCiYeH core_set_termios( tty: Arc<TtyCore>, arg: VirtAddr, opt: TtySetTermiosOpt, ) -> Result<usize, SystemError>19752da9a59SGnoCiYeH pub fn core_set_termios( 19852da9a59SGnoCiYeH tty: Arc<TtyCore>, 19952da9a59SGnoCiYeH arg: VirtAddr, 20052da9a59SGnoCiYeH opt: TtySetTermiosOpt, 20152da9a59SGnoCiYeH ) -> Result<usize, SystemError> { 202be60c929SGnoCiYeH #[allow(unused_assignments)] 203be60c929SGnoCiYeH // TERMIOS_TERMIO下会用到 204b5b571e0SLoGin let mut tmp_termios = *tty.core().termios(); 20552da9a59SGnoCiYeH 20652da9a59SGnoCiYeH if opt.contains(TtySetTermiosOpt::TERMIOS_TERMIO) { 20752da9a59SGnoCiYeH todo!() 20852da9a59SGnoCiYeH } else { 209be60c929SGnoCiYeH let user_reader = UserBufferReader::new( 21052da9a59SGnoCiYeH arg.as_ptr::<PosixTermios>(), 21152da9a59SGnoCiYeH core::mem::size_of::<PosixTermios>(), 21252da9a59SGnoCiYeH true, 21352da9a59SGnoCiYeH )?; 21452da9a59SGnoCiYeH 215be60c929SGnoCiYeH let mut term = PosixTermios::default(); 216be60c929SGnoCiYeH user_reader.copy_one_from_user(&mut term, 0)?; 217be60c929SGnoCiYeH 218be60c929SGnoCiYeH tmp_termios = term.to_kernel_termios(); 21952da9a59SGnoCiYeH } 22052da9a59SGnoCiYeH 22152da9a59SGnoCiYeH if opt.contains(TtySetTermiosOpt::TERMIOS_FLUSH) { 222be60c929SGnoCiYeH let ld = tty.ldisc(); 22352da9a59SGnoCiYeH let _ = ld.flush_buffer(tty.clone()); 22452da9a59SGnoCiYeH } 22552da9a59SGnoCiYeH 22652da9a59SGnoCiYeH if opt.contains(TtySetTermiosOpt::TERMIOS_WAIT) { 22752da9a59SGnoCiYeH // TODO 22852da9a59SGnoCiYeH } 22952da9a59SGnoCiYeH 230be60c929SGnoCiYeH TtyCore::set_termios_next(tty, tmp_termios)?; 23152da9a59SGnoCiYeH Ok(0) 23252da9a59SGnoCiYeH } 23352da9a59SGnoCiYeH set_termios_next(tty: Arc<TtyCore>, new_termios: Termios) -> Result<(), SystemError>234be60c929SGnoCiYeH pub fn set_termios_next(tty: Arc<TtyCore>, new_termios: Termios) -> Result<(), SystemError> { 235be60c929SGnoCiYeH let mut termios = tty.core().termios_write(); 23652da9a59SGnoCiYeH 237b5b571e0SLoGin let old_termios = *termios; 23852da9a59SGnoCiYeH *termios = new_termios; 23952da9a59SGnoCiYeH let tmp = termios.control_mode; 24052da9a59SGnoCiYeH termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB; 24152da9a59SGnoCiYeH 242*9365e801SGnoCiYeH drop(termios); 243be60c929SGnoCiYeH let ret = tty.set_termios(tty.clone(), old_termios); 244*9365e801SGnoCiYeH let mut termios = tty.core().termios_write(); 24552da9a59SGnoCiYeH if ret.is_err() { 24652da9a59SGnoCiYeH termios.control_mode &= ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL; 24752da9a59SGnoCiYeH termios.control_mode |= old_termios.control_mode 24852da9a59SGnoCiYeH & !(ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL); 24952da9a59SGnoCiYeH termios.input_speed = old_termios.input_speed; 25052da9a59SGnoCiYeH termios.output_speed = old_termios.output_speed; 25152da9a59SGnoCiYeH } 25252da9a59SGnoCiYeH 25352da9a59SGnoCiYeH drop(termios); 254be60c929SGnoCiYeH let ld = tty.ldisc(); 25552da9a59SGnoCiYeH ld.set_termios(tty, Some(old_termios))?; 25652da9a59SGnoCiYeH 25752da9a59SGnoCiYeH Ok(()) 25852da9a59SGnoCiYeH } 259*9365e801SGnoCiYeH tty_do_resize(&self, windowsize: WindowSize) -> Result<(), SystemError>260*9365e801SGnoCiYeH pub fn tty_do_resize(&self, windowsize: WindowSize) -> Result<(), SystemError> { 261*9365e801SGnoCiYeH // TODO: 向前台进程发送信号 262*9365e801SGnoCiYeH *self.core.window_size_write() = windowsize; 263*9365e801SGnoCiYeH Ok(()) 264*9365e801SGnoCiYeH } 26552da9a59SGnoCiYeH } 26652da9a59SGnoCiYeH 267b5b571e0SLoGin #[derive(Debug, Default)] 26852da9a59SGnoCiYeH pub struct TtyContorlInfo { 26952da9a59SGnoCiYeH /// 前台进程pid 27052da9a59SGnoCiYeH pub session: Option<Pid>, 27152da9a59SGnoCiYeH /// 前台进程组id 27252da9a59SGnoCiYeH pub pgid: Option<Pid>, 27352da9a59SGnoCiYeH 27452da9a59SGnoCiYeH /// packet模式下使用,目前未用到 275dfe53cf0SGnoCiYeH pub pktstatus: TtyPacketStatus, 27652da9a59SGnoCiYeH pub packet: bool, 27752da9a59SGnoCiYeH } 27852da9a59SGnoCiYeH 27952da9a59SGnoCiYeH #[derive(Debug, Default)] 28052da9a59SGnoCiYeH pub struct TtyFlowState { 28152da9a59SGnoCiYeH /// 表示流控是否被停止 28252da9a59SGnoCiYeH pub stopped: bool, 28352da9a59SGnoCiYeH /// 表示 TCO(Transmit Continuous Operation)流控是否被停止 28452da9a59SGnoCiYeH pub tco_stopped: bool, 28552da9a59SGnoCiYeH } 28652da9a59SGnoCiYeH 28752da9a59SGnoCiYeH #[derive(Debug)] 28852da9a59SGnoCiYeH pub struct TtyCoreData { 28952da9a59SGnoCiYeH tty_driver: Arc<TtyDriver>, 29052da9a59SGnoCiYeH termios: RwLock<Termios>, 29152da9a59SGnoCiYeH name: String, 29252da9a59SGnoCiYeH flags: RwLock<TtyFlag>, 29352da9a59SGnoCiYeH /// 在初始化时即确定不会更改,所以这里不用加锁 29452da9a59SGnoCiYeH index: usize, 29559fdb447SLoGin count: AtomicUsize, 29652da9a59SGnoCiYeH /// 窗口大小 29752da9a59SGnoCiYeH window_size: RwLock<WindowSize>, 29852da9a59SGnoCiYeH /// 读等待队列 29952da9a59SGnoCiYeH read_wq: EventWaitQueue, 30052da9a59SGnoCiYeH /// 写等待队列 30152da9a59SGnoCiYeH write_wq: EventWaitQueue, 30252da9a59SGnoCiYeH /// 端口 30352da9a59SGnoCiYeH port: RwLock<Option<Arc<dyn TtyPort>>>, 30452da9a59SGnoCiYeH /// 前台进程 30552da9a59SGnoCiYeH ctrl: SpinLock<TtyContorlInfo>, 30652da9a59SGnoCiYeH /// 是否正在关闭 30752da9a59SGnoCiYeH closing: AtomicBool, 30852da9a59SGnoCiYeH /// 流控状态 30952da9a59SGnoCiYeH flow: SpinLock<TtyFlowState>, 310be60c929SGnoCiYeH /// 链接tty 311dfe53cf0SGnoCiYeH link: RwLock<Weak<TtyCore>>, 31252bcb59eSGnoCiYeH /// epitems 31352bcb59eSGnoCiYeH epitems: SpinLock<LinkedList<Arc<EPollItem>>>, 31452da9a59SGnoCiYeH } 31552da9a59SGnoCiYeH 31652da9a59SGnoCiYeH impl TtyCoreData { 31752da9a59SGnoCiYeH #[inline] driver(&self) -> Arc<TtyDriver>31852da9a59SGnoCiYeH pub fn driver(&self) -> Arc<TtyDriver> { 31952da9a59SGnoCiYeH self.tty_driver.clone() 32052da9a59SGnoCiYeH } 32152da9a59SGnoCiYeH 32252da9a59SGnoCiYeH #[inline] flow_irqsave(&self) -> SpinLockGuard<TtyFlowState>32352da9a59SGnoCiYeH pub fn flow_irqsave(&self) -> SpinLockGuard<TtyFlowState> { 32452da9a59SGnoCiYeH self.flow.lock_irqsave() 32552da9a59SGnoCiYeH } 32652da9a59SGnoCiYeH 32752da9a59SGnoCiYeH #[inline] port(&self) -> Option<Arc<dyn TtyPort>>32852da9a59SGnoCiYeH pub fn port(&self) -> Option<Arc<dyn TtyPort>> { 32952da9a59SGnoCiYeH self.port.read().clone() 33052da9a59SGnoCiYeH } 33152da9a59SGnoCiYeH 33252da9a59SGnoCiYeH #[inline] index(&self) -> usize33352da9a59SGnoCiYeH pub fn index(&self) -> usize { 33452da9a59SGnoCiYeH self.index 33552da9a59SGnoCiYeH } 33652da9a59SGnoCiYeH 33752da9a59SGnoCiYeH #[inline] name(&self) -> String33852da9a59SGnoCiYeH pub fn name(&self) -> String { 33952da9a59SGnoCiYeH self.name.clone() 34052da9a59SGnoCiYeH } 34152da9a59SGnoCiYeH 34252da9a59SGnoCiYeH #[inline] flags(&self) -> TtyFlag34352da9a59SGnoCiYeH pub fn flags(&self) -> TtyFlag { 344b5b571e0SLoGin *self.flags.read_irqsave() 34552da9a59SGnoCiYeH } 34652da9a59SGnoCiYeH 34752da9a59SGnoCiYeH #[inline] flags_write(&self) -> RwLockWriteGuard<'_, TtyFlag>348dfe53cf0SGnoCiYeH pub fn flags_write(&self) -> RwLockWriteGuard<'_, TtyFlag> { 349dfe53cf0SGnoCiYeH self.flags.write_irqsave() 350dfe53cf0SGnoCiYeH } 351dfe53cf0SGnoCiYeH 352dfe53cf0SGnoCiYeH #[inline] termios(&self) -> RwLockReadGuard<'_, Termios>35352da9a59SGnoCiYeH pub fn termios(&self) -> RwLockReadGuard<'_, Termios> { 35452bcb59eSGnoCiYeH self.termios.read_irqsave() 35552da9a59SGnoCiYeH } 35652da9a59SGnoCiYeH 35752da9a59SGnoCiYeH #[inline] termios_write(&self) -> RwLockWriteGuard<Termios>35852da9a59SGnoCiYeH pub fn termios_write(&self) -> RwLockWriteGuard<Termios> { 35952bcb59eSGnoCiYeH self.termios.write_irqsave() 36052da9a59SGnoCiYeH } 36152da9a59SGnoCiYeH 36252da9a59SGnoCiYeH #[inline] set_termios(&self, termios: Termios)36352da9a59SGnoCiYeH pub fn set_termios(&self, termios: Termios) { 36459fdb447SLoGin let mut termios_guard = self.termios_write(); 36552da9a59SGnoCiYeH *termios_guard = termios; 36652da9a59SGnoCiYeH } 36752da9a59SGnoCiYeH 36852da9a59SGnoCiYeH #[inline] count(&self) -> usize369dfe53cf0SGnoCiYeH pub fn count(&self) -> usize { 370dfe53cf0SGnoCiYeH self.count.load(Ordering::SeqCst) 371dfe53cf0SGnoCiYeH } 372dfe53cf0SGnoCiYeH 373dfe53cf0SGnoCiYeH #[inline] add_count(&self)37452da9a59SGnoCiYeH pub fn add_count(&self) { 37559fdb447SLoGin self.count 37659fdb447SLoGin .fetch_add(1, core::sync::atomic::Ordering::SeqCst); 37752da9a59SGnoCiYeH } 37852da9a59SGnoCiYeH 37952da9a59SGnoCiYeH #[inline] read_wq(&self) -> &EventWaitQueue38052da9a59SGnoCiYeH pub fn read_wq(&self) -> &EventWaitQueue { 38152da9a59SGnoCiYeH &self.read_wq 38252da9a59SGnoCiYeH } 38352da9a59SGnoCiYeH 38452da9a59SGnoCiYeH #[inline] write_wq(&self) -> &EventWaitQueue38552da9a59SGnoCiYeH pub fn write_wq(&self) -> &EventWaitQueue { 38652da9a59SGnoCiYeH &self.write_wq 38752da9a59SGnoCiYeH } 38852da9a59SGnoCiYeH 38952da9a59SGnoCiYeH #[inline] contorl_info_irqsave(&self) -> SpinLockGuard<TtyContorlInfo>39052da9a59SGnoCiYeH pub fn contorl_info_irqsave(&self) -> SpinLockGuard<TtyContorlInfo> { 39152da9a59SGnoCiYeH self.ctrl.lock_irqsave() 39252da9a59SGnoCiYeH } 39352da9a59SGnoCiYeH 39452da9a59SGnoCiYeH #[inline] window_size_upgradeable(&self) -> RwLockUpgradableGuard<WindowSize>39552da9a59SGnoCiYeH pub fn window_size_upgradeable(&self) -> RwLockUpgradableGuard<WindowSize> { 39652da9a59SGnoCiYeH self.window_size.upgradeable_read() 39752da9a59SGnoCiYeH } 39852da9a59SGnoCiYeH 39952da9a59SGnoCiYeH #[inline] window_size(&self) -> RwLockReadGuard<WindowSize>40052da9a59SGnoCiYeH pub fn window_size(&self) -> RwLockReadGuard<WindowSize> { 40152da9a59SGnoCiYeH self.window_size.read() 40252da9a59SGnoCiYeH } 40352da9a59SGnoCiYeH 40452da9a59SGnoCiYeH #[inline] window_size_write(&self) -> RwLockWriteGuard<WindowSize>405*9365e801SGnoCiYeH pub fn window_size_write(&self) -> RwLockWriteGuard<WindowSize> { 406*9365e801SGnoCiYeH self.window_size.write() 407*9365e801SGnoCiYeH } 408*9365e801SGnoCiYeH 409*9365e801SGnoCiYeH #[inline] is_closing(&self) -> bool41052da9a59SGnoCiYeH pub fn is_closing(&self) -> bool { 41152da9a59SGnoCiYeH self.closing.load(core::sync::atomic::Ordering::SeqCst) 41252da9a59SGnoCiYeH } 41352da9a59SGnoCiYeH 41452da9a59SGnoCiYeH #[inline] vc_data_irqsave(&self) -> SpinLockGuard<VirtualConsoleData>41552da9a59SGnoCiYeH pub fn vc_data_irqsave(&self) -> SpinLockGuard<VirtualConsoleData> { 41652da9a59SGnoCiYeH VIRT_CONSOLES[self.index].lock_irqsave() 41752da9a59SGnoCiYeH } 418be60c929SGnoCiYeH 419be60c929SGnoCiYeH #[inline] link(&self) -> Option<Arc<TtyCore>>420be60c929SGnoCiYeH pub fn link(&self) -> Option<Arc<TtyCore>> { 421dfe53cf0SGnoCiYeH self.link.read().upgrade() 422dfe53cf0SGnoCiYeH } 423dfe53cf0SGnoCiYeH checked_link(&self) -> Result<Arc<TtyCore>, SystemError>424dfe53cf0SGnoCiYeH pub fn checked_link(&self) -> Result<Arc<TtyCore>, SystemError> { 425dfe53cf0SGnoCiYeH if let Some(link) = self.link() { 426dfe53cf0SGnoCiYeH return Ok(link); 427dfe53cf0SGnoCiYeH } 428dfe53cf0SGnoCiYeH return Err(SystemError::ENODEV); 429dfe53cf0SGnoCiYeH } 430dfe53cf0SGnoCiYeH set_link(&self, link: Weak<TtyCore>)431dfe53cf0SGnoCiYeH pub fn set_link(&self, link: Weak<TtyCore>) { 432dfe53cf0SGnoCiYeH *self.link.write() = link; 433dfe53cf0SGnoCiYeH } 434dfe53cf0SGnoCiYeH init_termios(&self)435dfe53cf0SGnoCiYeH pub fn init_termios(&self) { 436dfe53cf0SGnoCiYeH let tty_index = self.index(); 437dfe53cf0SGnoCiYeH let driver = self.driver(); 438dfe53cf0SGnoCiYeH // 初始化termios 439dfe53cf0SGnoCiYeH if !driver 440dfe53cf0SGnoCiYeH .flags() 441dfe53cf0SGnoCiYeH .contains(super::tty_driver::TtyDriverFlag::TTY_DRIVER_RESET_TERMIOS) 442dfe53cf0SGnoCiYeH { 443dfe53cf0SGnoCiYeH // 先查看是否有已经保存的termios 444dfe53cf0SGnoCiYeH if let Some(t) = driver.saved_termios().get(tty_index) { 445dfe53cf0SGnoCiYeH let mut termios = *t; 446dfe53cf0SGnoCiYeH termios.line = driver.init_termios().line; 447dfe53cf0SGnoCiYeH self.set_termios(termios); 448dfe53cf0SGnoCiYeH } 449dfe53cf0SGnoCiYeH } 450dfe53cf0SGnoCiYeH // TODO:设置termios波特率? 451be60c929SGnoCiYeH } 45252bcb59eSGnoCiYeH 45352bcb59eSGnoCiYeH #[inline] add_epitem(&self, epitem: Arc<EPollItem>)45452bcb59eSGnoCiYeH pub fn add_epitem(&self, epitem: Arc<EPollItem>) { 45552bcb59eSGnoCiYeH self.epitems.lock().push_back(epitem) 45652bcb59eSGnoCiYeH } 45752da9a59SGnoCiYeH } 45852da9a59SGnoCiYeH 45952da9a59SGnoCiYeH impl TtyOperation for TtyCore { 46052da9a59SGnoCiYeH #[inline] open(&self, tty: &TtyCoreData) -> Result<(), SystemError>46152da9a59SGnoCiYeH fn open(&self, tty: &TtyCoreData) -> Result<(), SystemError> { 46252da9a59SGnoCiYeH return self.core().tty_driver.driver_funcs().open(tty); 46352da9a59SGnoCiYeH } 46452da9a59SGnoCiYeH 46552da9a59SGnoCiYeH #[inline] write_room(&self, tty: &TtyCoreData) -> usize46652da9a59SGnoCiYeH fn write_room(&self, tty: &TtyCoreData) -> usize { 46752da9a59SGnoCiYeH return self.core().tty_driver.driver_funcs().write_room(tty); 46852da9a59SGnoCiYeH } 46952da9a59SGnoCiYeH 47052da9a59SGnoCiYeH #[inline] write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError>47152da9a59SGnoCiYeH fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError> { 472f3b05a97SGnoCiYeH send_to_default_serial8250_port(buf); 47352da9a59SGnoCiYeH return self.core().tty_driver.driver_funcs().write(tty, buf, nr); 47452da9a59SGnoCiYeH } 47552da9a59SGnoCiYeH 47652da9a59SGnoCiYeH #[inline] flush_chars(&self, tty: &TtyCoreData)47752da9a59SGnoCiYeH fn flush_chars(&self, tty: &TtyCoreData) { 47852da9a59SGnoCiYeH self.core().tty_driver.driver_funcs().flush_chars(tty); 47952da9a59SGnoCiYeH } 48052da9a59SGnoCiYeH 48152da9a59SGnoCiYeH #[inline] put_char(&self, tty: &TtyCoreData, ch: u8) -> Result<(), SystemError>48252da9a59SGnoCiYeH fn put_char(&self, tty: &TtyCoreData, ch: u8) -> Result<(), SystemError> { 48352da9a59SGnoCiYeH return self.core().tty_driver.driver_funcs().put_char(tty, ch); 48452da9a59SGnoCiYeH } 48552da9a59SGnoCiYeH 48652da9a59SGnoCiYeH #[inline] install(&self, driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError>48752da9a59SGnoCiYeH fn install(&self, driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> { 48852da9a59SGnoCiYeH return self.core().tty_driver.driver_funcs().install(driver, tty); 48952da9a59SGnoCiYeH } 49052da9a59SGnoCiYeH 49152da9a59SGnoCiYeH #[inline] start(&self, tty: &TtyCoreData) -> Result<(), SystemError>49252da9a59SGnoCiYeH fn start(&self, tty: &TtyCoreData) -> Result<(), SystemError> { 49352da9a59SGnoCiYeH return self.core().tty_driver.driver_funcs().start(tty); 49452da9a59SGnoCiYeH } 49552da9a59SGnoCiYeH 49652da9a59SGnoCiYeH #[inline] stop(&self, tty: &TtyCoreData) -> Result<(), SystemError>49752da9a59SGnoCiYeH fn stop(&self, tty: &TtyCoreData) -> Result<(), SystemError> { 49852da9a59SGnoCiYeH return self.core().tty_driver.driver_funcs().stop(tty); 49952da9a59SGnoCiYeH } 50052da9a59SGnoCiYeH 50152da9a59SGnoCiYeH #[inline] ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError>50252da9a59SGnoCiYeH fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError> { 50352da9a59SGnoCiYeH return self.core().tty_driver.driver_funcs().ioctl(tty, cmd, arg); 50452da9a59SGnoCiYeH } 50552da9a59SGnoCiYeH 50652da9a59SGnoCiYeH #[inline] chars_in_buffer(&self) -> usize50752da9a59SGnoCiYeH fn chars_in_buffer(&self) -> usize { 50852da9a59SGnoCiYeH return self.core().tty_driver.driver_funcs().chars_in_buffer(); 50952da9a59SGnoCiYeH } 51052da9a59SGnoCiYeH 51152da9a59SGnoCiYeH #[inline] set_termios(&self, tty: Arc<TtyCore>, old_termios: Termios) -> Result<(), SystemError>51252da9a59SGnoCiYeH fn set_termios(&self, tty: Arc<TtyCore>, old_termios: Termios) -> Result<(), SystemError> { 51352da9a59SGnoCiYeH return self 51452da9a59SGnoCiYeH .core() 51552da9a59SGnoCiYeH .tty_driver 51652da9a59SGnoCiYeH .driver_funcs() 51752da9a59SGnoCiYeH .set_termios(tty, old_termios); 51852da9a59SGnoCiYeH } 519dfe53cf0SGnoCiYeH close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>520dfe53cf0SGnoCiYeH fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> { 521dfe53cf0SGnoCiYeH self.core().tty_driver.driver_funcs().close(tty) 522dfe53cf0SGnoCiYeH } 523*9365e801SGnoCiYeH resize(&self, tty: Arc<TtyCore>, winsize: WindowSize) -> Result<(), SystemError>524*9365e801SGnoCiYeH fn resize(&self, tty: Arc<TtyCore>, winsize: WindowSize) -> Result<(), SystemError> { 525*9365e801SGnoCiYeH self.core.tty_driver.driver_funcs().resize(tty, winsize) 526*9365e801SGnoCiYeH } 52752da9a59SGnoCiYeH } 52852da9a59SGnoCiYeH 52952da9a59SGnoCiYeH bitflags! { 53052da9a59SGnoCiYeH pub struct TtyFlag: u32 { 53152da9a59SGnoCiYeH /// 终端被节流 53252da9a59SGnoCiYeH const THROTTLED = 1 << 0; 53352da9a59SGnoCiYeH /// 终端输入输出错误状态 53452da9a59SGnoCiYeH const IO_ERROR = 1 << 1; 53552da9a59SGnoCiYeH /// 终端的其他一方已关闭 53652da9a59SGnoCiYeH const OTHER_CLOSED = 1 << 2; 53752da9a59SGnoCiYeH /// 终端处于独占状态 53852da9a59SGnoCiYeH const EXCLUSIVE = 1 << 3; 53952da9a59SGnoCiYeH /// 终端执行写唤醒操作 54052da9a59SGnoCiYeH const DO_WRITE_WAKEUP = 1 << 5; 54152da9a59SGnoCiYeH /// 终端线路驱动程序已打开 54252da9a59SGnoCiYeH const LDISC_OPEN = 1 << 11; 54352da9a59SGnoCiYeH /// 终端伪终端设备已锁定 54452da9a59SGnoCiYeH const PTY_LOCK = 1 << 16; 54552da9a59SGnoCiYeH /// 终端禁用写分裂操作 54652da9a59SGnoCiYeH const NO_WRITE_SPLIT = 1 << 17; 54752da9a59SGnoCiYeH /// 终端挂断(挂起)状态 54852da9a59SGnoCiYeH const HUPPED = 1 << 18; 54952da9a59SGnoCiYeH /// 终端正在挂断(挂起) 55052da9a59SGnoCiYeH const HUPPING = 1 << 19; 55152da9a59SGnoCiYeH /// 终端线路驱动程序正在更改 55252da9a59SGnoCiYeH const LDISC_CHANGING = 1 << 20; 55352da9a59SGnoCiYeH /// 终端线路驱动程序已停止 55452da9a59SGnoCiYeH const LDISC_HALTED = 1 << 22; 55552da9a59SGnoCiYeH } 556dfe53cf0SGnoCiYeH 557dfe53cf0SGnoCiYeH #[derive(Default)] 558dfe53cf0SGnoCiYeH pub struct TtyPacketStatus: u8 { 559dfe53cf0SGnoCiYeH /* Used for packet mode */ 560dfe53cf0SGnoCiYeH const TIOCPKT_DATA = 0; 561dfe53cf0SGnoCiYeH const TIOCPKT_FLUSHREAD = 1; 562dfe53cf0SGnoCiYeH const TIOCPKT_FLUSHWRITE = 2; 563dfe53cf0SGnoCiYeH const TIOCPKT_STOP = 4; 564dfe53cf0SGnoCiYeH const TIOCPKT_START = 8; 565dfe53cf0SGnoCiYeH const TIOCPKT_NOSTOP = 16; 566dfe53cf0SGnoCiYeH const TIOCPKT_DOSTOP = 32; 567dfe53cf0SGnoCiYeH const TIOCPKT_IOCTL = 64; 568dfe53cf0SGnoCiYeH } 56952da9a59SGnoCiYeH } 57052da9a59SGnoCiYeH 57152da9a59SGnoCiYeH #[derive(Debug, PartialEq)] 57252da9a59SGnoCiYeH pub enum EchoOperation { 57352da9a59SGnoCiYeH /// 开始特殊操作。 57452da9a59SGnoCiYeH Start, 57552da9a59SGnoCiYeH /// 向后移动光标列。 57652da9a59SGnoCiYeH MoveBackCol, 57752da9a59SGnoCiYeH /// 设置规范模式下的列位置。 57852da9a59SGnoCiYeH SetCanonCol, 57952da9a59SGnoCiYeH /// 擦除制表符。 58052da9a59SGnoCiYeH EraseTab, 58152da9a59SGnoCiYeH 58252da9a59SGnoCiYeH Undefined(u8), 58352da9a59SGnoCiYeH } 58452da9a59SGnoCiYeH 58552da9a59SGnoCiYeH impl EchoOperation { from_u8(num: u8) -> EchoOperation58652da9a59SGnoCiYeH pub fn from_u8(num: u8) -> EchoOperation { 58752da9a59SGnoCiYeH match num { 58852da9a59SGnoCiYeH 0xff => Self::Start, 58952da9a59SGnoCiYeH 0x80 => Self::MoveBackCol, 59052da9a59SGnoCiYeH 0x81 => Self::SetCanonCol, 59152da9a59SGnoCiYeH 0x82 => Self::EraseTab, 59252da9a59SGnoCiYeH _ => Self::Undefined(num), 59352da9a59SGnoCiYeH } 59452da9a59SGnoCiYeH } 59552da9a59SGnoCiYeH to_u8(&self) -> u859652da9a59SGnoCiYeH pub fn to_u8(&self) -> u8 { 59752da9a59SGnoCiYeH match *self { 59852da9a59SGnoCiYeH EchoOperation::Start => 0xff, 59952da9a59SGnoCiYeH EchoOperation::MoveBackCol => 0x80, 60052da9a59SGnoCiYeH EchoOperation::SetCanonCol => 0x81, 60152da9a59SGnoCiYeH EchoOperation::EraseTab => 0x82, 60252da9a59SGnoCiYeH EchoOperation::Undefined(num) => num, 60352da9a59SGnoCiYeH } 60452da9a59SGnoCiYeH } 60552da9a59SGnoCiYeH } 60652da9a59SGnoCiYeH 60752da9a59SGnoCiYeH pub struct TtyIoctlCmd; 60852da9a59SGnoCiYeH 60952da9a59SGnoCiYeH #[allow(dead_code)] 61052da9a59SGnoCiYeH impl TtyIoctlCmd { 61152da9a59SGnoCiYeH /// 获取终端参数 61252da9a59SGnoCiYeH pub const TCGETS: u32 = 0x5401; 61352da9a59SGnoCiYeH /// 设置终端参数 61452da9a59SGnoCiYeH pub const TCSETS: u32 = 0x5402; 61552da9a59SGnoCiYeH /// 设置终端参数并等待所有输出完成 61652da9a59SGnoCiYeH pub const TCSETSW: u32 = 0x5403; 61752da9a59SGnoCiYeH /// 设置终端参数并且等待所有输出完成,但在这之前将终端清空 61852da9a59SGnoCiYeH pub const TCSETSF: u32 = 0x5404; 61952da9a59SGnoCiYeH /// 获取终端参数 62052da9a59SGnoCiYeH pub const TCGETA: u32 = 0x5405; 62152da9a59SGnoCiYeH /// 设置终端参数 62252da9a59SGnoCiYeH pub const TCSETA: u32 = 0x5406; 62352da9a59SGnoCiYeH /// 设置终端参数并等待所有输出完成 62452da9a59SGnoCiYeH pub const TCSETAW: u32 = 0x5407; 62552da9a59SGnoCiYeH /// 设置终端参数并且等待所有输出完成,但在这之前将终端清空 62652da9a59SGnoCiYeH pub const TCSETAF: u32 = 0x5408; 62752da9a59SGnoCiYeH /// 发送零字节,等待所有输出完成 62852da9a59SGnoCiYeH pub const TCSBRK: u32 = 0x5409; 62952da9a59SGnoCiYeH /// 控制终端的流控 63052da9a59SGnoCiYeH pub const TCXONC: u32 = 0x540A; 63152da9a59SGnoCiYeH /// 刷新输入/输出缓冲区或者丢弃输入缓冲区 63252da9a59SGnoCiYeH pub const TCFLSH: u32 = 0x540B; 63352da9a59SGnoCiYeH /// 设置设备为独占模式 63452da9a59SGnoCiYeH pub const TIOCEXCL: u32 = 0x540C; 63552da9a59SGnoCiYeH /// 设置设备为非独占模式 63652da9a59SGnoCiYeH pub const TIOCNXCL: u32 = 0x540D; 63752da9a59SGnoCiYeH /// 设置当前进程的控制终端 63852da9a59SGnoCiYeH pub const TIOCSCTTY: u32 = 0x540E; 63952da9a59SGnoCiYeH /// 获取前台进程组 64052da9a59SGnoCiYeH pub const TIOCGPGRP: u32 = 0x540F; 64152da9a59SGnoCiYeH ///设置前台进程组 64252da9a59SGnoCiYeH pub const TIOCSPGRP: u32 = 0x5410; 64352da9a59SGnoCiYeH /// 获取输出队列的字节数 64452da9a59SGnoCiYeH pub const TIOCOUTQ: u32 = 0x5411; 64552da9a59SGnoCiYeH /// 模拟从终端输入字符 64652da9a59SGnoCiYeH pub const TIOCSTI: u32 = 0x5412; 64752da9a59SGnoCiYeH /// 获取窗口大小 64852da9a59SGnoCiYeH pub const TIOCGWINSZ: u32 = 0x5413; 64952da9a59SGnoCiYeH /// 设置窗口大小 65052da9a59SGnoCiYeH pub const TIOCSWINSZ: u32 = 0x5414; 65152da9a59SGnoCiYeH /// 获取终端控制信号的状态 65252da9a59SGnoCiYeH pub const TIOCMGET: u32 = 0x5415; 65352da9a59SGnoCiYeH /// 设置终端控制信号的位 65452da9a59SGnoCiYeH pub const TIOCMBIS: u32 = 0x5416; 65552da9a59SGnoCiYeH /// 清除终端控制信号的位 65652da9a59SGnoCiYeH pub const TIOCMBIC: u32 = 0x5417; 65752da9a59SGnoCiYeH /// 设置终端控制信号的状态 65852da9a59SGnoCiYeH pub const TIOCMSET: u32 = 0x5418; 65952da9a59SGnoCiYeH /// 获取软件载波状态 66052da9a59SGnoCiYeH pub const TIOCGSOFTCAR: u32 = 0x5419; 66152da9a59SGnoCiYeH /// 设置软件载波状态 66252da9a59SGnoCiYeH pub const TIOCSSOFTCAR: u32 = 0x541A; 66352da9a59SGnoCiYeH /// 获取输入队列的字节数 66452da9a59SGnoCiYeH pub const FIONREAD: u32 = 0x541B; 66552da9a59SGnoCiYeH /// Linux 特有命令 66652da9a59SGnoCiYeH pub const TIOCLINUX: u32 = 0x541C; 66752da9a59SGnoCiYeH /// 获取控制台设备 66852da9a59SGnoCiYeH pub const TIOCCONS: u32 = 0x541D; 66952da9a59SGnoCiYeH /// 获取串行设备参数 67052da9a59SGnoCiYeH pub const TIOCGSERIAL: u32 = 0x541E; 67152da9a59SGnoCiYeH /// 设置串行设备参数 67252da9a59SGnoCiYeH pub const TIOCSSERIAL: u32 = 0x541F; 67352da9a59SGnoCiYeH /// 设置套接字的报文模式 67452da9a59SGnoCiYeH pub const TIOCPKT: u32 = 0x5420; 67552da9a59SGnoCiYeH /// 设置非阻塞 I/O 67652da9a59SGnoCiYeH pub const FIONBIO: u32 = 0x5421; 67752da9a59SGnoCiYeH /// 清除控制终端 67852da9a59SGnoCiYeH pub const TIOCNOTTY: u32 = 0x5422; 67952da9a59SGnoCiYeH /// 设置终端线路驱动器 68052da9a59SGnoCiYeH pub const TIOCSETD: u32 = 0x5423; 68152da9a59SGnoCiYeH /// 获取终端线路驱动器 68252da9a59SGnoCiYeH pub const TIOCGETD: u32 = 0x5424; 68352da9a59SGnoCiYeH /// 发送终止条件 68452da9a59SGnoCiYeH pub const TCSBRKP: u32 = 0x5425; 68552da9a59SGnoCiYeH /// 开始发送零比特 68652da9a59SGnoCiYeH pub const TIOCSBRK: u32 = 0x5427; 68752da9a59SGnoCiYeH /// 停止发送零比特 68852da9a59SGnoCiYeH pub const TIOCCBRK: u32 = 0x5428; 68952da9a59SGnoCiYeH /// Return the session ID of FD 69052da9a59SGnoCiYeH pub const TIOCGSID: u32 = 0x5429; 691dfe53cf0SGnoCiYeH /// 设置ptl锁标记 692dfe53cf0SGnoCiYeH pub const TIOCSPTLCK: u32 = 0x40045431; 693dfe53cf0SGnoCiYeH /// 获取ptl锁标记 694dfe53cf0SGnoCiYeH pub const TIOCGPTLCK: u32 = 0x80045439; 695dfe53cf0SGnoCiYeH /// 获取packet标记 696dfe53cf0SGnoCiYeH pub const TIOCGPKT: u32 = 0x80045438; 697dfe53cf0SGnoCiYeH /// 获取pts index 698dfe53cf0SGnoCiYeH pub const TIOCGPTN: u32 = 0x80045430; 69952da9a59SGnoCiYeH } 700