xref: /DragonOS/kernel/src/driver/tty/tty_core.rs (revision bd70d2d1f490aabd570a5301b858bd5eb04149fa)
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