xref: /DragonOS/kernel/src/driver/tty/tty_ldisc/ntty.rs (revision a1fc824fcc3bd4c2e267d8c0e9e3866fc7310bba)
152bcb59eSGnoCiYeH use core::intrinsics::likely;
252da9a59SGnoCiYeH use core::ops::BitXor;
352da9a59SGnoCiYeH 
452da9a59SGnoCiYeH use bitmap::{traits::BitMapOps, StaticBitmap};
552da9a59SGnoCiYeH 
652da9a59SGnoCiYeH use alloc::sync::{Arc, Weak};
752da9a59SGnoCiYeH use system_error::SystemError;
852da9a59SGnoCiYeH 
952da9a59SGnoCiYeH use crate::{
1052da9a59SGnoCiYeH     arch::ipc::signal::Signal,
1152da9a59SGnoCiYeH     driver::tty::{
1252da9a59SGnoCiYeH         termios::{ControlCharIndex, InputMode, LocalMode, OutputMode, Termios},
13dfe53cf0SGnoCiYeH         tty_core::{EchoOperation, TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd, TtyPacketStatus},
1452da9a59SGnoCiYeH         tty_driver::{TtyDriverFlag, TtyOperation},
1552da9a59SGnoCiYeH         tty_job_control::TtyJobCtrlManager,
1652da9a59SGnoCiYeH     },
1752da9a59SGnoCiYeH     filesystem::vfs::file::FileMode,
1852da9a59SGnoCiYeH     libs::{
1952da9a59SGnoCiYeH         rwlock::RwLockReadGuard,
2052da9a59SGnoCiYeH         spinlock::{SpinLock, SpinLockGuard},
2152da9a59SGnoCiYeH     },
2252da9a59SGnoCiYeH     mm::VirtAddr,
2352da9a59SGnoCiYeH     net::event_poll::EPollEventType,
2452da9a59SGnoCiYeH     process::ProcessManager,
2552da9a59SGnoCiYeH     syscall::{user_access::UserBufferWriter, Syscall},
2652da9a59SGnoCiYeH };
2752da9a59SGnoCiYeH 
2852da9a59SGnoCiYeH use super::TtyLineDiscipline;
2952da9a59SGnoCiYeH pub const NTTY_BUFSIZE: usize = 4096;
3052da9a59SGnoCiYeH pub const ECHO_COMMIT_WATERMARK: usize = 256;
3152da9a59SGnoCiYeH pub const ECHO_BLOCK: usize = 256;
3252da9a59SGnoCiYeH pub const ECHO_DISCARD_WATERMARK: usize = NTTY_BUFSIZE - (ECHO_BLOCK + 32);
3352da9a59SGnoCiYeH 
ntty_buf_mask(idx: usize) -> usize3452da9a59SGnoCiYeH fn ntty_buf_mask(idx: usize) -> usize {
3552da9a59SGnoCiYeH     return idx & (NTTY_BUFSIZE - 1);
3652da9a59SGnoCiYeH }
3752da9a59SGnoCiYeH 
3852da9a59SGnoCiYeH #[derive(Debug)]
3952da9a59SGnoCiYeH pub struct NTtyLinediscipline {
4052da9a59SGnoCiYeH     pub data: SpinLock<NTtyData>,
4152da9a59SGnoCiYeH }
4252da9a59SGnoCiYeH 
4352da9a59SGnoCiYeH impl NTtyLinediscipline {
4452da9a59SGnoCiYeH     #[inline]
disc_data(&self) -> SpinLockGuard<NTtyData>4552da9a59SGnoCiYeH     pub fn disc_data(&self) -> SpinLockGuard<NTtyData> {
4652da9a59SGnoCiYeH         self.data.lock_irqsave()
4752da9a59SGnoCiYeH     }
4852da9a59SGnoCiYeH 
4952da9a59SGnoCiYeH     #[inline]
disc_data_try_lock(&self) -> Result<SpinLockGuard<NTtyData>, SystemError>5052da9a59SGnoCiYeH     pub fn disc_data_try_lock(&self) -> Result<SpinLockGuard<NTtyData>, SystemError> {
5152da9a59SGnoCiYeH         self.data.try_lock_irqsave()
5252da9a59SGnoCiYeH     }
5352da9a59SGnoCiYeH 
ioctl_helper(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError>5452da9a59SGnoCiYeH     fn ioctl_helper(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> {
5552da9a59SGnoCiYeH         match cmd {
5652da9a59SGnoCiYeH             TtyIoctlCmd::TCXONC => {
5752da9a59SGnoCiYeH                 todo!()
5852da9a59SGnoCiYeH             }
5952da9a59SGnoCiYeH             TtyIoctlCmd::TCFLSH => {
6052da9a59SGnoCiYeH                 todo!()
6152da9a59SGnoCiYeH             }
6252da9a59SGnoCiYeH             _ => {
63be60c929SGnoCiYeH                 return TtyCore::tty_mode_ioctl(tty.clone(), cmd, arg);
6452da9a59SGnoCiYeH             }
6552da9a59SGnoCiYeH         }
6652da9a59SGnoCiYeH     }
6752da9a59SGnoCiYeH }
6852da9a59SGnoCiYeH 
6952da9a59SGnoCiYeH #[derive(Debug)]
7052da9a59SGnoCiYeH pub struct NTtyData {
7152da9a59SGnoCiYeH     /// 写者管理,tty只有一个写者,即ttydevice,所以不需要加锁
7252da9a59SGnoCiYeH     /// 读取缓冲区的头指针,表示下一个将要接受进buf的字符的位置
7352da9a59SGnoCiYeH     read_head: usize,
7452da9a59SGnoCiYeH     ///  提交缓冲区的头指针,用于行规程处理
7552da9a59SGnoCiYeH     commit_head: usize,
7652da9a59SGnoCiYeH     /// 规范缓冲区的头指针,用于规范模式的处理
7752da9a59SGnoCiYeH     canon_head: usize,
7852da9a59SGnoCiYeH     /// 回显缓冲区的头指针,用于存储需要回显的字符
7952da9a59SGnoCiYeH     echo_head: usize,
8052da9a59SGnoCiYeH     /// 回显过程中用于提交的头指针
8152da9a59SGnoCiYeH     echo_commit: usize,
8252da9a59SGnoCiYeH     /// 标记回显字符的起始位置
8352da9a59SGnoCiYeH     echo_mark: usize,
8452da9a59SGnoCiYeH 
8552da9a59SGnoCiYeH     /// 读者管理
8652da9a59SGnoCiYeH     /// 读取字符的尾指针,即当前读取位置
8752da9a59SGnoCiYeH     read_tail: usize,
8852da9a59SGnoCiYeH     /// 行的起始位置
8952da9a59SGnoCiYeH     line_start: usize,
9052da9a59SGnoCiYeH     /// 预读字符数,用于处理控制字符
9152da9a59SGnoCiYeH     lookahead_count: usize,
9252da9a59SGnoCiYeH 
9352da9a59SGnoCiYeH     // 更改以下六个标记时必须持有termios的锁
9452da9a59SGnoCiYeH     /// Line-next 标志,表示下一个输入字符应当按字面处理
9552da9a59SGnoCiYeH     lnext: bool,
9652da9a59SGnoCiYeH     /// 擦除状态的标志
9752da9a59SGnoCiYeH     erasing: bool,
9852da9a59SGnoCiYeH     /// Raw 模式的标志
9952da9a59SGnoCiYeH     raw: bool,
10052da9a59SGnoCiYeH     /// Real raw 模式的标志
10152da9a59SGnoCiYeH     real_raw: bool,
10252da9a59SGnoCiYeH     /// 规范模式的标志
10352da9a59SGnoCiYeH     icanon: bool,
10452da9a59SGnoCiYeH     /// 是否开启echo
10552da9a59SGnoCiYeH     echo: bool,
10652da9a59SGnoCiYeH     ///  标志是否正在进行推送
10752da9a59SGnoCiYeH     pushing: bool,
10852da9a59SGnoCiYeH     /// 是否没有空间可写
10952da9a59SGnoCiYeH     no_room: bool,
11052da9a59SGnoCiYeH 
11152da9a59SGnoCiYeH     /// 光标所在列
11252da9a59SGnoCiYeH     cursor_column: u32,
11352da9a59SGnoCiYeH     /// 规范模式下光标所在列
11452da9a59SGnoCiYeH     canon_cursor_column: u32,
11552da9a59SGnoCiYeH     /// 回显缓冲区的尾指针
11652da9a59SGnoCiYeH     echo_tail: usize,
11752da9a59SGnoCiYeH 
11852da9a59SGnoCiYeH     /// 写者与读者共享
11952da9a59SGnoCiYeH     read_buf: [u8; NTTY_BUFSIZE],
12052da9a59SGnoCiYeH     echo_buf: [u8; NTTY_BUFSIZE],
12152da9a59SGnoCiYeH 
12252da9a59SGnoCiYeH     read_flags: StaticBitmap<NTTY_BUFSIZE>,
12352da9a59SGnoCiYeH     char_map: StaticBitmap<256>,
12452da9a59SGnoCiYeH 
1259365e801SGnoCiYeH     tty: Weak<TtyCore>,
12652da9a59SGnoCiYeH }
12752da9a59SGnoCiYeH 
12852da9a59SGnoCiYeH impl NTtyData {
new() -> Self12952da9a59SGnoCiYeH     pub fn new() -> Self {
13052da9a59SGnoCiYeH         Self {
13152da9a59SGnoCiYeH             read_head: 0,
13252da9a59SGnoCiYeH             commit_head: 0,
13352da9a59SGnoCiYeH             canon_head: 0,
13452da9a59SGnoCiYeH             echo_head: 0,
13552da9a59SGnoCiYeH             echo_commit: 0,
13652da9a59SGnoCiYeH             echo_mark: 0,
13752da9a59SGnoCiYeH             read_tail: 0,
13852da9a59SGnoCiYeH             line_start: 0,
13952da9a59SGnoCiYeH             lookahead_count: 0,
14052da9a59SGnoCiYeH             lnext: false,
14152da9a59SGnoCiYeH             erasing: false,
14252da9a59SGnoCiYeH             raw: false,
14352da9a59SGnoCiYeH             real_raw: false,
14452da9a59SGnoCiYeH             icanon: false,
14552da9a59SGnoCiYeH             pushing: false,
14652da9a59SGnoCiYeH             echo: false,
14752da9a59SGnoCiYeH             cursor_column: 0,
14852da9a59SGnoCiYeH             canon_cursor_column: 0,
14952da9a59SGnoCiYeH             echo_tail: 0,
15052da9a59SGnoCiYeH             read_buf: [0; NTTY_BUFSIZE],
15152da9a59SGnoCiYeH             echo_buf: [0; NTTY_BUFSIZE],
15252da9a59SGnoCiYeH             read_flags: StaticBitmap::new(),
15352da9a59SGnoCiYeH             char_map: StaticBitmap::new(),
1549365e801SGnoCiYeH             tty: Weak::default(),
15552da9a59SGnoCiYeH             no_room: false,
15652da9a59SGnoCiYeH         }
15752da9a59SGnoCiYeH     }
15852da9a59SGnoCiYeH 
15952da9a59SGnoCiYeH     #[inline]
read_cnt(&self) -> usize16052da9a59SGnoCiYeH     pub fn read_cnt(&self) -> usize {
16152da9a59SGnoCiYeH         self.read_head - self.read_tail
16252da9a59SGnoCiYeH     }
16352da9a59SGnoCiYeH 
16452da9a59SGnoCiYeH     #[inline]
read_at(&self, i: usize) -> u816552da9a59SGnoCiYeH     pub fn read_at(&self, i: usize) -> u8 {
16652da9a59SGnoCiYeH         let i = i & (NTTY_BUFSIZE - 1);
16752da9a59SGnoCiYeH         self.read_buf[i]
16852da9a59SGnoCiYeH     }
16952da9a59SGnoCiYeH 
17052da9a59SGnoCiYeH     /// ### 接收数据到NTTY
receive_buf_common( &mut self, tty: Arc<TtyCore>, buf: &[u8], flags: Option<&[u8]>, mut count: usize, flow: bool, ) -> Result<usize, SystemError>17152da9a59SGnoCiYeH     pub fn receive_buf_common(
17252da9a59SGnoCiYeH         &mut self,
17352da9a59SGnoCiYeH         tty: Arc<TtyCore>,
17452da9a59SGnoCiYeH         buf: &[u8],
17552da9a59SGnoCiYeH         flags: Option<&[u8]>,
17652da9a59SGnoCiYeH         mut count: usize,
17752da9a59SGnoCiYeH         flow: bool,
17852da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
17952da9a59SGnoCiYeH         // 获取termios读锁
18052da9a59SGnoCiYeH         let termios = tty.core().termios();
18152da9a59SGnoCiYeH         let mut overflow;
18252da9a59SGnoCiYeH         let mut n;
18352da9a59SGnoCiYeH         let mut offset = 0;
18452da9a59SGnoCiYeH         let mut recved = 0;
18552da9a59SGnoCiYeH         loop {
18652da9a59SGnoCiYeH             let tail = self.read_tail;
18752da9a59SGnoCiYeH 
18852da9a59SGnoCiYeH             let mut room = NTTY_BUFSIZE - (self.read_head - tail);
18952da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::PARMRK) {
19052da9a59SGnoCiYeH                 room = (room + 2) / 3;
19152da9a59SGnoCiYeH             }
19252da9a59SGnoCiYeH 
19352da9a59SGnoCiYeH             room -= 1;
19452da9a59SGnoCiYeH             if room == 0 || room > NTTY_BUFSIZE {
19552da9a59SGnoCiYeH                 // 可能溢出
19652da9a59SGnoCiYeH                 overflow = self.icanon && self.canon_head == tail;
19752da9a59SGnoCiYeH                 if room > NTTY_BUFSIZE && overflow {
19852da9a59SGnoCiYeH                     self.read_head -= 1;
19952da9a59SGnoCiYeH                 }
20052da9a59SGnoCiYeH                 self.no_room = flow && !overflow;
20152da9a59SGnoCiYeH                 room = if overflow { !0 } else { 0 }
20252da9a59SGnoCiYeH             } else {
20352da9a59SGnoCiYeH                 overflow = false;
20452da9a59SGnoCiYeH             }
20552da9a59SGnoCiYeH 
20652da9a59SGnoCiYeH             n = count.min(room);
20752da9a59SGnoCiYeH             if n == 0 {
20852da9a59SGnoCiYeH                 break;
20952da9a59SGnoCiYeH             }
21052da9a59SGnoCiYeH 
21152da9a59SGnoCiYeH             if !overflow {
212b5b571e0SLoGin                 if let Some(flags) = flags {
213b5b571e0SLoGin                     self.receive_buf(tty.clone(), &buf[offset..], Some(&flags[offset..]), n);
21452da9a59SGnoCiYeH                 } else {
215b5b571e0SLoGin                     self.receive_buf(tty.clone(), &buf[offset..], flags, n);
21652da9a59SGnoCiYeH                 }
21752da9a59SGnoCiYeH             }
21852da9a59SGnoCiYeH 
21952da9a59SGnoCiYeH             offset += n;
22052da9a59SGnoCiYeH 
22152da9a59SGnoCiYeH             count -= n;
22252da9a59SGnoCiYeH 
22352da9a59SGnoCiYeH             recved += n;
22452da9a59SGnoCiYeH 
22552da9a59SGnoCiYeH             if tty.core().flags().contains(TtyFlag::LDISC_CHANGING) {
22652da9a59SGnoCiYeH                 break;
22752da9a59SGnoCiYeH             }
22852da9a59SGnoCiYeH         }
22952da9a59SGnoCiYeH 
23052da9a59SGnoCiYeH         // TODO: throttle
23152da9a59SGnoCiYeH 
23252da9a59SGnoCiYeH         Ok(recved)
23352da9a59SGnoCiYeH     }
23452da9a59SGnoCiYeH 
receive_buf( &mut self, tty: Arc<TtyCore>, buf: &[u8], flags: Option<&[u8]>, count: usize, )23552da9a59SGnoCiYeH     pub fn receive_buf(
23652da9a59SGnoCiYeH         &mut self,
23752da9a59SGnoCiYeH         tty: Arc<TtyCore>,
23852da9a59SGnoCiYeH         buf: &[u8],
23952da9a59SGnoCiYeH         flags: Option<&[u8]>,
24052da9a59SGnoCiYeH         count: usize,
24152da9a59SGnoCiYeH     ) {
24252da9a59SGnoCiYeH         let termios = tty.core().termios();
24352da9a59SGnoCiYeH         let preops = termios.input_mode.contains(InputMode::ISTRIP)
24452da9a59SGnoCiYeH             || termios.input_mode.contains(InputMode::IUCLC)
24552da9a59SGnoCiYeH             || termios.local_mode.contains(LocalMode::IEXTEN);
24652da9a59SGnoCiYeH 
24752da9a59SGnoCiYeH         let look_ahead = self.lookahead_count.min(count);
24852da9a59SGnoCiYeH         if self.real_raw {
24952bcb59eSGnoCiYeH             self.receive_buf_real_raw(buf, count);
25052da9a59SGnoCiYeH         } else if self.raw || (termios.local_mode.contains(LocalMode::EXTPROC) && !preops) {
25152bcb59eSGnoCiYeH             self.receive_buf_raw(buf, flags, count);
25252da9a59SGnoCiYeH         } else if tty.core().is_closing() && !termios.local_mode.contains(LocalMode::EXTPROC) {
25352da9a59SGnoCiYeH             todo!()
25452da9a59SGnoCiYeH         } else {
25552da9a59SGnoCiYeH             if look_ahead > 0 {
25652da9a59SGnoCiYeH                 self.receive_buf_standard(tty.clone(), buf, flags, look_ahead, true);
25752da9a59SGnoCiYeH             }
25852da9a59SGnoCiYeH 
25952da9a59SGnoCiYeH             if count > look_ahead {
26052da9a59SGnoCiYeH                 self.receive_buf_standard(tty.clone(), buf, flags, count - look_ahead, false);
26152da9a59SGnoCiYeH             }
26252da9a59SGnoCiYeH 
26352da9a59SGnoCiYeH             // 刷新echo
26452da9a59SGnoCiYeH             self.flush_echoes(tty.clone());
26552da9a59SGnoCiYeH 
26652da9a59SGnoCiYeH             tty.flush_chars(tty.core());
26752da9a59SGnoCiYeH         }
26852da9a59SGnoCiYeH 
26952da9a59SGnoCiYeH         self.lookahead_count -= look_ahead;
27052da9a59SGnoCiYeH 
27152da9a59SGnoCiYeH         if self.icanon && !termios.local_mode.contains(LocalMode::EXTPROC) {
27252da9a59SGnoCiYeH             return;
27352da9a59SGnoCiYeH         }
27452da9a59SGnoCiYeH 
27552da9a59SGnoCiYeH         self.commit_head = self.read_head;
27652da9a59SGnoCiYeH 
27752da9a59SGnoCiYeH         if self.read_cnt() > 0 {
27852da9a59SGnoCiYeH             tty.core()
27952da9a59SGnoCiYeH                 .read_wq()
28052bcb59eSGnoCiYeH                 .wakeup_any((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDBAND).bits() as u64);
28152bcb59eSGnoCiYeH         }
28252bcb59eSGnoCiYeH     }
28352bcb59eSGnoCiYeH 
receive_buf_real_raw(&mut self, buf: &[u8], mut count: usize)28452bcb59eSGnoCiYeH     fn receive_buf_real_raw(&mut self, buf: &[u8], mut count: usize) {
28552bcb59eSGnoCiYeH         let mut head = ntty_buf_mask(self.read_head);
28652bcb59eSGnoCiYeH         let mut n = count.min(NTTY_BUFSIZE - head);
28752bcb59eSGnoCiYeH 
28852bcb59eSGnoCiYeH         // 假如有一部分在队列头部,则这部分是拷贝尾部部分
28952bcb59eSGnoCiYeH         self.read_buf[head..(head + n)].copy_from_slice(&buf[0..n]);
29052bcb59eSGnoCiYeH         self.read_head += n;
29152bcb59eSGnoCiYeH         count -= n;
29252bcb59eSGnoCiYeH         let offset = n;
29352bcb59eSGnoCiYeH 
29452bcb59eSGnoCiYeH         // 假如有一部分在队列头部,则这部分是拷贝头部部分
29552bcb59eSGnoCiYeH         head = ntty_buf_mask(self.read_head);
29652bcb59eSGnoCiYeH         n = count.min(NTTY_BUFSIZE - head);
29752bcb59eSGnoCiYeH         self.read_buf[head..(head + n)].copy_from_slice(&buf[offset..(offset + n)]);
29852bcb59eSGnoCiYeH         self.read_head += n;
29952bcb59eSGnoCiYeH     }
30052bcb59eSGnoCiYeH 
receive_buf_raw(&mut self, buf: &[u8], flags: Option<&[u8]>, mut count: usize)30152bcb59eSGnoCiYeH     fn receive_buf_raw(&mut self, buf: &[u8], flags: Option<&[u8]>, mut count: usize) {
30252bcb59eSGnoCiYeH         // TTY_NORMAL 目前这部分未做,所以先占位置而不做抽象
30352bcb59eSGnoCiYeH         let mut flag = 1;
30452bcb59eSGnoCiYeH         let mut f_offset = 0;
30552bcb59eSGnoCiYeH         let mut c_offset = 0;
30652bcb59eSGnoCiYeH         while count != 0 {
30752bcb59eSGnoCiYeH             if flags.is_some() {
30852bcb59eSGnoCiYeH                 flag = flags.as_ref().unwrap()[f_offset];
30952bcb59eSGnoCiYeH                 f_offset += 1;
31052bcb59eSGnoCiYeH             }
31152bcb59eSGnoCiYeH 
31252bcb59eSGnoCiYeH             if likely(flag == 1) {
31352bcb59eSGnoCiYeH                 self.read_buf[self.read_head] = buf[c_offset];
31452bcb59eSGnoCiYeH                 c_offset += 1;
31552bcb59eSGnoCiYeH                 self.read_head += 1;
31652bcb59eSGnoCiYeH             } else {
31752bcb59eSGnoCiYeH                 todo!()
31852bcb59eSGnoCiYeH             }
31952bcb59eSGnoCiYeH 
32052bcb59eSGnoCiYeH             count -= 1;
32152da9a59SGnoCiYeH         }
32252da9a59SGnoCiYeH     }
32352da9a59SGnoCiYeH 
flush_echoes(&mut self, tty: Arc<TtyCore>)32452da9a59SGnoCiYeH     pub fn flush_echoes(&mut self, tty: Arc<TtyCore>) {
32552da9a59SGnoCiYeH         let termios = tty.core().termios();
32652da9a59SGnoCiYeH         if !termios.local_mode.contains(LocalMode::ECHO)
32752da9a59SGnoCiYeH             && !termios.local_mode.contains(LocalMode::ECHONL)
32852da9a59SGnoCiYeH             || self.echo_commit == self.echo_head
32952da9a59SGnoCiYeH         {
33052da9a59SGnoCiYeH             return;
33152da9a59SGnoCiYeH         }
33252da9a59SGnoCiYeH 
33352da9a59SGnoCiYeH         self.echo_commit = self.echo_head;
33452da9a59SGnoCiYeH         drop(termios);
33552da9a59SGnoCiYeH         let _ = self.echoes(tty);
33652da9a59SGnoCiYeH     }
33752da9a59SGnoCiYeH 
receive_buf_standard( &mut self, tty: Arc<TtyCore>, buf: &[u8], flags: Option<&[u8]>, mut count: usize, lookahead_done: bool, )33852da9a59SGnoCiYeH     pub fn receive_buf_standard(
33952da9a59SGnoCiYeH         &mut self,
34052da9a59SGnoCiYeH         tty: Arc<TtyCore>,
34152da9a59SGnoCiYeH         buf: &[u8],
34252da9a59SGnoCiYeH         flags: Option<&[u8]>,
34352da9a59SGnoCiYeH         mut count: usize,
34452da9a59SGnoCiYeH         lookahead_done: bool,
34552da9a59SGnoCiYeH     ) {
34652da9a59SGnoCiYeH         let termios = tty.core().termios();
34752da9a59SGnoCiYeH         if flags.is_some() {
34852da9a59SGnoCiYeH             todo!("ntty recv buf flags todo");
34952da9a59SGnoCiYeH         }
35052da9a59SGnoCiYeH 
35152da9a59SGnoCiYeH         let mut offset = 0;
35252da9a59SGnoCiYeH         while count > 0 {
35352da9a59SGnoCiYeH             if offset >= buf.len() {
35452da9a59SGnoCiYeH                 break;
35552da9a59SGnoCiYeH             }
35652da9a59SGnoCiYeH             let mut c = buf[offset];
35752da9a59SGnoCiYeH             offset += 1;
35852da9a59SGnoCiYeH 
35952da9a59SGnoCiYeH             if self.lnext {
36052da9a59SGnoCiYeH                 // 将下一个字符当做字面值处理
36152da9a59SGnoCiYeH                 self.lnext = false;
36252da9a59SGnoCiYeH                 if termios.input_mode.contains(InputMode::ISTRIP) {
36352da9a59SGnoCiYeH                     c &= 0x7f;
36452da9a59SGnoCiYeH                 }
36552da9a59SGnoCiYeH 
36652da9a59SGnoCiYeH                 if termios.input_mode.contains(InputMode::IUCLC)
36752da9a59SGnoCiYeH                     && termios.local_mode.contains(LocalMode::IEXTEN)
36852da9a59SGnoCiYeH                 {
36952da9a59SGnoCiYeH                     c = (c as char).to_ascii_lowercase() as u8;
37052da9a59SGnoCiYeH                     self.receive_char(c, tty.clone())
37152da9a59SGnoCiYeH                 }
37252da9a59SGnoCiYeH 
37352da9a59SGnoCiYeH                 continue;
37452da9a59SGnoCiYeH             }
37552da9a59SGnoCiYeH 
37652da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::ISTRIP) {
37752da9a59SGnoCiYeH                 c &= 0x7f;
37852da9a59SGnoCiYeH             }
37952da9a59SGnoCiYeH 
38052da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::IUCLC)
38152da9a59SGnoCiYeH                 && termios.local_mode.contains(LocalMode::IEXTEN)
38252da9a59SGnoCiYeH             {
38352da9a59SGnoCiYeH                 c = (c as char).to_ascii_lowercase() as u8;
38452da9a59SGnoCiYeH             }
38552da9a59SGnoCiYeH 
38652da9a59SGnoCiYeH             if termios.local_mode.contains(LocalMode::EXTPROC) {
38752da9a59SGnoCiYeH                 self.add_read_byte(c);
38852da9a59SGnoCiYeH                 continue;
38952da9a59SGnoCiYeH             }
39052da9a59SGnoCiYeH 
391*a1fc824fSLoGin             if ((c as usize) < self.char_map.size()) && self.char_map.get(c as usize).unwrap() {
39252da9a59SGnoCiYeH                 // 特殊字符
393*a1fc824fSLoGin                 self.receive_special_char(c, tty.clone(), lookahead_done);
39452da9a59SGnoCiYeH             } else {
39552da9a59SGnoCiYeH                 self.receive_char(c, tty.clone());
39652da9a59SGnoCiYeH             }
39752da9a59SGnoCiYeH 
39852da9a59SGnoCiYeH             count -= 1;
39952da9a59SGnoCiYeH         }
40052da9a59SGnoCiYeH     }
40152da9a59SGnoCiYeH 
40252bcb59eSGnoCiYeH     #[inline(never)]
receive_special_char(&mut self, mut c: u8, tty: Arc<TtyCore>, lookahead_done: bool)40352da9a59SGnoCiYeH     pub fn receive_special_char(&mut self, mut c: u8, tty: Arc<TtyCore>, lookahead_done: bool) {
40452da9a59SGnoCiYeH         let is_flow_ctrl = self.is_flow_ctrl_char(tty.clone(), c, lookahead_done);
40552da9a59SGnoCiYeH         let termios = tty.core().termios();
40652da9a59SGnoCiYeH 
40752da9a59SGnoCiYeH         // 启用软件流控,并且该字符已经当做软件流控字符处理
40852da9a59SGnoCiYeH         if termios.input_mode.contains(InputMode::IXON) && is_flow_ctrl {
40952da9a59SGnoCiYeH             return;
41052da9a59SGnoCiYeH         }
41152da9a59SGnoCiYeH 
41252da9a59SGnoCiYeH         if termios.local_mode.contains(LocalMode::ISIG) {
41352da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VINTR] {
41452da9a59SGnoCiYeH                 self.recv_sig_char(tty.clone(), &termios, Signal::SIGINT, c);
41552da9a59SGnoCiYeH                 return;
41652da9a59SGnoCiYeH             }
41752da9a59SGnoCiYeH 
41852da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VQUIT] {
41952da9a59SGnoCiYeH                 self.recv_sig_char(tty.clone(), &termios, Signal::SIGQUIT, c);
42052da9a59SGnoCiYeH                 return;
42152da9a59SGnoCiYeH             }
42252da9a59SGnoCiYeH 
42352da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VSUSP] {
42452da9a59SGnoCiYeH                 self.recv_sig_char(tty.clone(), &termios, Signal::SIGTSTP, c);
42552da9a59SGnoCiYeH                 return;
42652da9a59SGnoCiYeH             }
42752da9a59SGnoCiYeH         }
42852da9a59SGnoCiYeH 
42952da9a59SGnoCiYeH         let flow = tty.core().flow_irqsave();
43052da9a59SGnoCiYeH         if flow.stopped
43152da9a59SGnoCiYeH             && !flow.tco_stopped
43252da9a59SGnoCiYeH             && termios.input_mode.contains(InputMode::IXON)
43352da9a59SGnoCiYeH             && termios.input_mode.contains(InputMode::IXANY)
43452da9a59SGnoCiYeH         {
43552da9a59SGnoCiYeH             tty.tty_start();
43652da9a59SGnoCiYeH             self.process_echoes(tty.clone());
43752da9a59SGnoCiYeH         }
43852da9a59SGnoCiYeH         drop(flow);
43952da9a59SGnoCiYeH 
44052da9a59SGnoCiYeH         if c == b'\r' {
44152da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::IGNCR) {
44252da9a59SGnoCiYeH                 // 忽略
44352da9a59SGnoCiYeH                 return;
44452da9a59SGnoCiYeH             }
44552da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::ICRNL) {
44652da9a59SGnoCiYeH                 // 映射为换行
44752da9a59SGnoCiYeH                 c = b'\n';
44852da9a59SGnoCiYeH             }
44952da9a59SGnoCiYeH         } else if c == b'\n' && termios.input_mode.contains(InputMode::INLCR) {
45052da9a59SGnoCiYeH             // 映射为回车
45152da9a59SGnoCiYeH             c = b'\r';
45252da9a59SGnoCiYeH         }
45352da9a59SGnoCiYeH 
45452da9a59SGnoCiYeH         if self.icanon {
45552da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VERASE]
45652da9a59SGnoCiYeH                 || c == termios.control_characters[ControlCharIndex::VKILL]
45752da9a59SGnoCiYeH                 || (c == termios.control_characters[ControlCharIndex::VWERASE]
45852da9a59SGnoCiYeH                     && termios.local_mode.contains(LocalMode::IEXTEN))
45952da9a59SGnoCiYeH             {
46052da9a59SGnoCiYeH                 self.eraser(c, &termios);
46152da9a59SGnoCiYeH                 self.commit_echoes(tty.clone());
46252da9a59SGnoCiYeH                 return;
46352da9a59SGnoCiYeH             }
46452da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VLNEXT]
46552da9a59SGnoCiYeH                 && termios.local_mode.contains(LocalMode::IEXTEN)
46652da9a59SGnoCiYeH             {
46752da9a59SGnoCiYeH                 self.lnext = true;
46852da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::ECHO) {
46952da9a59SGnoCiYeH                     self.finish_erasing();
47052da9a59SGnoCiYeH                     if termios.local_mode.contains(LocalMode::ECHOCTL) {
47152da9a59SGnoCiYeH                         self.echo_char_raw(b'^');
47252da9a59SGnoCiYeH                         self.echo_char_raw(8);
47352da9a59SGnoCiYeH                         self.commit_echoes(tty.clone());
47452da9a59SGnoCiYeH                     }
47552da9a59SGnoCiYeH                 }
47652da9a59SGnoCiYeH                 return;
47752da9a59SGnoCiYeH             }
47852da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VREPRINT]
47952da9a59SGnoCiYeH                 && termios.local_mode.contains(LocalMode::ECHO)
48052da9a59SGnoCiYeH                 && termios.local_mode.contains(LocalMode::IEXTEN)
48152da9a59SGnoCiYeH             {
48252da9a59SGnoCiYeH                 let mut tail = self.canon_head;
48352da9a59SGnoCiYeH                 self.finish_erasing();
48452da9a59SGnoCiYeH                 self.echo_char(c, &termios);
48552da9a59SGnoCiYeH                 self.echo_char_raw(b'\n');
48652da9a59SGnoCiYeH                 while ntty_buf_mask(tail) != ntty_buf_mask(self.read_head) {
48752da9a59SGnoCiYeH                     self.echo_char(self.read_buf[ntty_buf_mask(tail)], &termios);
48852da9a59SGnoCiYeH                     tail += 1;
48952da9a59SGnoCiYeH                 }
49052da9a59SGnoCiYeH                 self.commit_echoes(tty.clone());
49152da9a59SGnoCiYeH                 return;
49252da9a59SGnoCiYeH             }
49352da9a59SGnoCiYeH 
49452da9a59SGnoCiYeH             if c == b'\n' {
49552da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::ECHO)
49652da9a59SGnoCiYeH                     || termios.local_mode.contains(LocalMode::ECHONL)
49752da9a59SGnoCiYeH                 {
49852da9a59SGnoCiYeH                     self.echo_char_raw(b'\n');
49952da9a59SGnoCiYeH                     self.commit_echoes(tty.clone());
50052da9a59SGnoCiYeH                 }
50152da9a59SGnoCiYeH 
50252da9a59SGnoCiYeH                 self.read_flags.set(ntty_buf_mask(self.read_head), true);
50352da9a59SGnoCiYeH                 self.read_buf[ntty_buf_mask(self.read_head)] = c;
50452da9a59SGnoCiYeH                 self.read_head += 1;
50552da9a59SGnoCiYeH                 self.canon_head = self.read_head;
50652bcb59eSGnoCiYeH                 tty.core().read_wq().wakeup_any(
50752bcb59eSGnoCiYeH                     (EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64,
50852bcb59eSGnoCiYeH                 );
50952da9a59SGnoCiYeH                 return;
51052da9a59SGnoCiYeH             }
51152da9a59SGnoCiYeH 
51252da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VEOF] {
51352da9a59SGnoCiYeH                 c = ControlCharIndex::DISABLE_CHAR;
51452da9a59SGnoCiYeH 
51552da9a59SGnoCiYeH                 self.read_flags.set(ntty_buf_mask(self.read_head), true);
51652da9a59SGnoCiYeH                 self.read_buf[ntty_buf_mask(self.read_head)] = c;
51752da9a59SGnoCiYeH                 self.read_head += 1;
51852da9a59SGnoCiYeH                 self.canon_head = self.read_head;
51952bcb59eSGnoCiYeH                 tty.core().read_wq().wakeup_any(
52052bcb59eSGnoCiYeH                     (EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64,
52152bcb59eSGnoCiYeH                 );
52252da9a59SGnoCiYeH                 return;
52352da9a59SGnoCiYeH             }
52452da9a59SGnoCiYeH 
52552da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VEOL]
52652da9a59SGnoCiYeH                 || (c == termios.control_characters[ControlCharIndex::VEOL2]
52752da9a59SGnoCiYeH                     && termios.local_mode.contains(LocalMode::IEXTEN))
52852da9a59SGnoCiYeH             {
52952da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::ECHO) {
53052da9a59SGnoCiYeH                     if self.canon_head == self.read_head {
53152da9a59SGnoCiYeH                         self.add_echo_byte(EchoOperation::Start.to_u8());
53252da9a59SGnoCiYeH                         self.add_echo_byte(EchoOperation::SetCanonCol.to_u8());
53352da9a59SGnoCiYeH                     }
53452da9a59SGnoCiYeH                     self.echo_char(c, &termios);
53552da9a59SGnoCiYeH                     self.commit_echoes(tty.clone());
53652da9a59SGnoCiYeH                 }
53752da9a59SGnoCiYeH 
53852da9a59SGnoCiYeH                 if c == 0o377 && termios.input_mode.contains(InputMode::PARMRK) {
53952da9a59SGnoCiYeH                     self.read_buf[ntty_buf_mask(self.read_head)] = c;
54052da9a59SGnoCiYeH                     self.read_head += 1;
54152da9a59SGnoCiYeH                 }
54252da9a59SGnoCiYeH 
54352da9a59SGnoCiYeH                 self.read_flags.set(ntty_buf_mask(self.read_head), true);
54452da9a59SGnoCiYeH                 self.read_buf[ntty_buf_mask(self.read_head)] = c;
54552da9a59SGnoCiYeH                 self.read_head += 1;
54652da9a59SGnoCiYeH                 self.canon_head = self.read_head;
54752bcb59eSGnoCiYeH                 tty.core().read_wq().wakeup_any(
54852bcb59eSGnoCiYeH                     (EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64,
54952bcb59eSGnoCiYeH                 );
55052da9a59SGnoCiYeH                 return;
55152da9a59SGnoCiYeH             }
55252da9a59SGnoCiYeH         }
55352da9a59SGnoCiYeH 
55452da9a59SGnoCiYeH         if termios.local_mode.contains(LocalMode::ECHO) {
55552da9a59SGnoCiYeH             self.finish_erasing();
55652da9a59SGnoCiYeH             if c == b'\n' {
55752da9a59SGnoCiYeH                 self.echo_char_raw(b'\n');
55852da9a59SGnoCiYeH             } else {
55952da9a59SGnoCiYeH                 if self.canon_head == self.read_head {
56052da9a59SGnoCiYeH                     self.add_echo_byte(EchoOperation::Start.to_u8());
56152da9a59SGnoCiYeH                     self.add_echo_byte(EchoOperation::SetCanonCol.to_u8());
56252da9a59SGnoCiYeH                 }
56352da9a59SGnoCiYeH                 self.echo_char(c, &termios);
56452da9a59SGnoCiYeH             }
56552da9a59SGnoCiYeH 
56652da9a59SGnoCiYeH             self.commit_echoes(tty.clone());
56752da9a59SGnoCiYeH         }
56852da9a59SGnoCiYeH 
56952da9a59SGnoCiYeH         if c == 0o377 && termios.input_mode.contains(InputMode::PARMRK) {
57052da9a59SGnoCiYeH             self.read_buf[ntty_buf_mask(self.read_head)] = c;
57152da9a59SGnoCiYeH             self.read_head += 1;
57252da9a59SGnoCiYeH         }
57352da9a59SGnoCiYeH 
57452da9a59SGnoCiYeH         self.read_buf[ntty_buf_mask(self.read_head)] = c;
57552da9a59SGnoCiYeH         self.read_head += 1;
57652da9a59SGnoCiYeH     }
57752da9a59SGnoCiYeH 
57852da9a59SGnoCiYeH     /// ## ntty默认eraser function
57952bcb59eSGnoCiYeH     #[inline(never)]
eraser(&mut self, mut c: u8, termios: &RwLockReadGuard<Termios>)58052da9a59SGnoCiYeH     fn eraser(&mut self, mut c: u8, termios: &RwLockReadGuard<Termios>) {
58152da9a59SGnoCiYeH         if self.read_head == self.canon_head {
58252da9a59SGnoCiYeH             return;
58352da9a59SGnoCiYeH         }
58452da9a59SGnoCiYeH 
58552da9a59SGnoCiYeH         let erase = c == termios.control_characters[ControlCharIndex::VERASE];
58652da9a59SGnoCiYeH         let werase = c == termios.control_characters[ControlCharIndex::VWERASE];
58752da9a59SGnoCiYeH         let kill = !erase && !werase;
58852da9a59SGnoCiYeH 
58952da9a59SGnoCiYeH         if kill {
59052da9a59SGnoCiYeH             if !termios.local_mode.contains(LocalMode::ECHO) {
59152da9a59SGnoCiYeH                 self.read_head = self.canon_head;
59252da9a59SGnoCiYeH                 return;
59352da9a59SGnoCiYeH             }
59452da9a59SGnoCiYeH             if !termios.local_mode.contains(LocalMode::ECHOK)
59552da9a59SGnoCiYeH                 || !termios.local_mode.contains(LocalMode::ECHOKE)
59652da9a59SGnoCiYeH                 || !termios.local_mode.contains(LocalMode::ECHOE)
59752da9a59SGnoCiYeH             {
59852da9a59SGnoCiYeH                 self.read_head = self.canon_head;
59952da9a59SGnoCiYeH                 if self.erasing {
60052da9a59SGnoCiYeH                     self.echo_char_raw(c);
60152da9a59SGnoCiYeH                     self.erasing = false;
60252da9a59SGnoCiYeH                 }
60352da9a59SGnoCiYeH                 self.echo_char(c, termios);
60452da9a59SGnoCiYeH 
60552da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::ECHOK) {
60652da9a59SGnoCiYeH                     // 添加新行
60752da9a59SGnoCiYeH                     self.echo_char_raw(b'\n');
60852da9a59SGnoCiYeH                 }
60952da9a59SGnoCiYeH                 return;
61052da9a59SGnoCiYeH             }
61152da9a59SGnoCiYeH         }
61252da9a59SGnoCiYeH 
61352da9a59SGnoCiYeH         let mut head;
61452da9a59SGnoCiYeH         let mut cnt;
61552da9a59SGnoCiYeH         while ntty_buf_mask(self.read_head) != ntty_buf_mask(self.canon_head) {
61652da9a59SGnoCiYeH             head = self.read_head;
61752da9a59SGnoCiYeH 
61852da9a59SGnoCiYeH             loop {
61952da9a59SGnoCiYeH                 // 消除多字节字符
62052da9a59SGnoCiYeH                 head -= 1;
62152da9a59SGnoCiYeH                 c = self.read_buf[ntty_buf_mask(head)];
62252da9a59SGnoCiYeH 
62352da9a59SGnoCiYeH                 if !(Self::is_continuation(c, termios)
62452da9a59SGnoCiYeH                     && ntty_buf_mask(head) != ntty_buf_mask(self.canon_head))
62552da9a59SGnoCiYeH                 {
62652da9a59SGnoCiYeH                     break;
62752da9a59SGnoCiYeH                 }
62852da9a59SGnoCiYeH             }
62952da9a59SGnoCiYeH 
63052da9a59SGnoCiYeH             if Self::is_continuation(c, termios) {
63152da9a59SGnoCiYeH                 break;
63252da9a59SGnoCiYeH             }
63352da9a59SGnoCiYeH 
63452da9a59SGnoCiYeH             if werase {
63552da9a59SGnoCiYeH                 todo!()
63652da9a59SGnoCiYeH             }
63752da9a59SGnoCiYeH 
63852da9a59SGnoCiYeH             cnt = self.read_head - head;
63952da9a59SGnoCiYeH             self.read_head = head;
64052da9a59SGnoCiYeH             if termios.local_mode.contains(LocalMode::ECHO) {
64152da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::ECHOPRT) {
64252da9a59SGnoCiYeH                     if !self.erasing {
64352da9a59SGnoCiYeH                         self.echo_char_raw(b'\\');
64452da9a59SGnoCiYeH                         self.erasing = true;
64552da9a59SGnoCiYeH                     }
64652da9a59SGnoCiYeH                     self.echo_char(c, termios);
64752da9a59SGnoCiYeH                     cnt -= 1;
64852da9a59SGnoCiYeH                     while cnt > 0 {
64952da9a59SGnoCiYeH                         cnt -= 1;
65052da9a59SGnoCiYeH                         head += 1;
65152da9a59SGnoCiYeH                         self.echo_char_raw(self.read_buf[ntty_buf_mask(head)]);
65252da9a59SGnoCiYeH                         self.add_echo_byte(EchoOperation::Start.to_u8());
65352da9a59SGnoCiYeH                         self.add_echo_byte(EchoOperation::MoveBackCol.to_u8());
65452da9a59SGnoCiYeH                     }
65552da9a59SGnoCiYeH                 } else if erase && !termios.local_mode.contains(LocalMode::ECHOE) {
65652da9a59SGnoCiYeH                     self.echo_char(
65752da9a59SGnoCiYeH                         termios.control_characters[ControlCharIndex::VERASE],
65852da9a59SGnoCiYeH                         termios,
65952da9a59SGnoCiYeH                     );
66052da9a59SGnoCiYeH                 } else if c == b'\t' {
66152da9a59SGnoCiYeH                     let mut num_chars = 0;
66252da9a59SGnoCiYeH                     let mut after_tab = false;
66352da9a59SGnoCiYeH                     let mut tail = self.read_head;
66452da9a59SGnoCiYeH 
66552da9a59SGnoCiYeH                     while ntty_buf_mask(tail) != ntty_buf_mask(self.canon_head) {
66652da9a59SGnoCiYeH                         tail -= 1;
66752da9a59SGnoCiYeH                         c = self.read_buf[ntty_buf_mask(tail)];
66852da9a59SGnoCiYeH                         if c == b'\t' {
66952da9a59SGnoCiYeH                             after_tab = true;
67052da9a59SGnoCiYeH                             break;
67152da9a59SGnoCiYeH                         } else if (c as char).is_control() {
67252da9a59SGnoCiYeH                             if termios.local_mode.contains(LocalMode::ECHOCTL) {
67352da9a59SGnoCiYeH                                 num_chars += 2;
67452da9a59SGnoCiYeH                             }
67552da9a59SGnoCiYeH                         } else if !Self::is_continuation(c, termios) {
67652da9a59SGnoCiYeH                             num_chars += 1;
67752da9a59SGnoCiYeH                         }
67852da9a59SGnoCiYeH                     }
67952da9a59SGnoCiYeH 
68052da9a59SGnoCiYeH                     self.echo_erase_tab(num_chars, after_tab);
68152da9a59SGnoCiYeH                 } else {
68252da9a59SGnoCiYeH                     if (c as char).is_control() && termios.local_mode.contains(LocalMode::ECHOCTL) {
68352da9a59SGnoCiYeH                         // 8 => '\b'
68452da9a59SGnoCiYeH                         self.echo_char_raw(8);
68552da9a59SGnoCiYeH                         self.echo_char_raw(b' ');
68652da9a59SGnoCiYeH                         self.echo_char_raw(8);
68752da9a59SGnoCiYeH                     }
68852da9a59SGnoCiYeH 
68952da9a59SGnoCiYeH                     if !(c as char).is_control() || termios.local_mode.contains(LocalMode::ECHOCTL)
69052da9a59SGnoCiYeH                     {
69152da9a59SGnoCiYeH                         // 8 => '\b'
69252da9a59SGnoCiYeH                         self.echo_char_raw(8);
69352da9a59SGnoCiYeH                         self.echo_char_raw(b' ');
69452da9a59SGnoCiYeH                         self.echo_char_raw(8);
69552da9a59SGnoCiYeH                     }
69652da9a59SGnoCiYeH                 }
69752da9a59SGnoCiYeH             }
69852da9a59SGnoCiYeH 
69952da9a59SGnoCiYeH             if erase {
70052da9a59SGnoCiYeH                 break;
70152da9a59SGnoCiYeH             }
70252da9a59SGnoCiYeH         }
70352da9a59SGnoCiYeH 
70452da9a59SGnoCiYeH         if self.read_head == self.canon_head && termios.local_mode.contains(LocalMode::ECHO) {
70552da9a59SGnoCiYeH             self.finish_erasing();
70652da9a59SGnoCiYeH         }
70752da9a59SGnoCiYeH     }
70852da9a59SGnoCiYeH 
finish_erasing(&mut self)70952da9a59SGnoCiYeH     fn finish_erasing(&mut self) {
71052da9a59SGnoCiYeH         if self.erasing {
71152da9a59SGnoCiYeH             self.echo_char_raw(b'/');
71252da9a59SGnoCiYeH             self.erasing = false;
71352da9a59SGnoCiYeH         }
71452da9a59SGnoCiYeH     }
71552da9a59SGnoCiYeH 
echo_erase_tab(&mut self, mut num: u8, after_tab: bool)71652da9a59SGnoCiYeH     fn echo_erase_tab(&mut self, mut num: u8, after_tab: bool) {
71752da9a59SGnoCiYeH         self.add_echo_byte(EchoOperation::Start.to_u8());
71852da9a59SGnoCiYeH         self.add_echo_byte(EchoOperation::EraseTab.to_u8());
71952da9a59SGnoCiYeH 
72052da9a59SGnoCiYeH         num &= 7;
72152da9a59SGnoCiYeH 
72252da9a59SGnoCiYeH         if after_tab {
72352da9a59SGnoCiYeH             num |= 0x80;
72452da9a59SGnoCiYeH         }
72552da9a59SGnoCiYeH 
72652da9a59SGnoCiYeH         self.add_echo_byte(num);
72752da9a59SGnoCiYeH     }
72852da9a59SGnoCiYeH 
72952da9a59SGnoCiYeH     /// ## 多字节字符检测
73052da9a59SGnoCiYeH     /// 检测是否为多字节字符的后续字节
is_continuation(c: u8, termios: &RwLockReadGuard<Termios>) -> bool73152da9a59SGnoCiYeH     fn is_continuation(c: u8, termios: &RwLockReadGuard<Termios>) -> bool {
73252da9a59SGnoCiYeH         return termios.input_mode.contains(InputMode::IUTF8) && (c & 0xc0) == 0x80;
73352da9a59SGnoCiYeH     }
73452da9a59SGnoCiYeH 
73552da9a59SGnoCiYeH     /// ## 该字符是否已经当做流控字符处理
is_flow_ctrl_char(&mut self, tty: Arc<TtyCore>, c: u8, lookahead_done: bool) -> bool73652da9a59SGnoCiYeH     pub fn is_flow_ctrl_char(&mut self, tty: Arc<TtyCore>, c: u8, lookahead_done: bool) -> bool {
73752da9a59SGnoCiYeH         let termios = tty.core().termios();
73852da9a59SGnoCiYeH 
73952da9a59SGnoCiYeH         if !(termios.control_characters[ControlCharIndex::VSTART] == c
74052da9a59SGnoCiYeH             || termios.control_characters[ControlCharIndex::VSTOP] == c)
74152da9a59SGnoCiYeH         {
74252da9a59SGnoCiYeH             return false;
74352da9a59SGnoCiYeH         }
74452da9a59SGnoCiYeH 
74552da9a59SGnoCiYeH         if lookahead_done {
74652da9a59SGnoCiYeH             return true;
74752da9a59SGnoCiYeH         }
74852da9a59SGnoCiYeH 
74952da9a59SGnoCiYeH         if termios.control_characters[ControlCharIndex::VSTART] == c {
75052da9a59SGnoCiYeH             tty.tty_start();
75152da9a59SGnoCiYeH             self.process_echoes(tty.clone());
75252da9a59SGnoCiYeH             return true;
75352da9a59SGnoCiYeH         } else {
75452da9a59SGnoCiYeH             tty.tty_stop();
75552da9a59SGnoCiYeH             return true;
75652da9a59SGnoCiYeH         }
75752da9a59SGnoCiYeH     }
75852da9a59SGnoCiYeH 
75952da9a59SGnoCiYeH     /// ## 接收到信号字符时的处理
recv_sig_char( &mut self, tty: Arc<TtyCore>, termios: &RwLockReadGuard<Termios>, signal: Signal, c: u8, )76052da9a59SGnoCiYeH     fn recv_sig_char(
76152da9a59SGnoCiYeH         &mut self,
76252da9a59SGnoCiYeH         tty: Arc<TtyCore>,
76352da9a59SGnoCiYeH         termios: &RwLockReadGuard<Termios>,
76452da9a59SGnoCiYeH         signal: Signal,
76552da9a59SGnoCiYeH         c: u8,
76652da9a59SGnoCiYeH     ) {
76752da9a59SGnoCiYeH         self.input_signal(tty.clone(), termios, signal);
76852da9a59SGnoCiYeH         if termios.input_mode.contains(InputMode::IXON) {
76952da9a59SGnoCiYeH             tty.tty_start();
77052da9a59SGnoCiYeH         }
77152da9a59SGnoCiYeH 
77252da9a59SGnoCiYeH         if termios.local_mode.contains(LocalMode::ECHO) {
77352da9a59SGnoCiYeH             self.echo_char(c, termios);
77452da9a59SGnoCiYeH             self.commit_echoes(tty);
77552da9a59SGnoCiYeH         } else {
77652da9a59SGnoCiYeH             self.process_echoes(tty);
77752da9a59SGnoCiYeH         }
77852da9a59SGnoCiYeH     }
77952da9a59SGnoCiYeH 
78052da9a59SGnoCiYeH     /// ## 处理输入信号
input_signal( &mut self, tty: Arc<TtyCore>, termios: &RwLockReadGuard<Termios>, signal: Signal, )78152da9a59SGnoCiYeH     pub fn input_signal(
78252da9a59SGnoCiYeH         &mut self,
78352da9a59SGnoCiYeH         tty: Arc<TtyCore>,
78452da9a59SGnoCiYeH         termios: &RwLockReadGuard<Termios>,
78552da9a59SGnoCiYeH         signal: Signal,
78652da9a59SGnoCiYeH     ) {
78752da9a59SGnoCiYeH         // 先处理信号
78852da9a59SGnoCiYeH         let mut ctrl_info = tty.core().contorl_info_irqsave();
78952da9a59SGnoCiYeH         let pg = ctrl_info.pgid;
790b5b571e0SLoGin         if let Some(pg) = pg {
791b5b571e0SLoGin             let _ = Syscall::kill(pg, signal as i32);
79252da9a59SGnoCiYeH         }
79352da9a59SGnoCiYeH 
79452da9a59SGnoCiYeH         ctrl_info.pgid = None;
79552da9a59SGnoCiYeH         ctrl_info.session = None;
79652da9a59SGnoCiYeH 
79752da9a59SGnoCiYeH         if !termios.local_mode.contains(LocalMode::NOFLSH) {
79852da9a59SGnoCiYeH             // 重置
79952da9a59SGnoCiYeH             self.echo_head = 0;
80052da9a59SGnoCiYeH             self.echo_tail = 0;
80152da9a59SGnoCiYeH             self.echo_mark = 0;
80252da9a59SGnoCiYeH             self.echo_commit = 0;
80352da9a59SGnoCiYeH 
80452da9a59SGnoCiYeH             let _ = tty.flush_buffer(tty.core());
80552da9a59SGnoCiYeH 
80652da9a59SGnoCiYeH             self.read_head = 0;
80752da9a59SGnoCiYeH             self.canon_head = 0;
80852da9a59SGnoCiYeH             self.read_tail = 0;
80952da9a59SGnoCiYeH             self.line_start = 0;
81052da9a59SGnoCiYeH 
81152da9a59SGnoCiYeH             self.erasing = false;
81252da9a59SGnoCiYeH             self.read_flags.set_all(false);
81352da9a59SGnoCiYeH             self.pushing = false;
81452da9a59SGnoCiYeH             self.lookahead_count = 0;
815dfe53cf0SGnoCiYeH 
816dfe53cf0SGnoCiYeH             if tty.core().link().is_some() {
817dfe53cf0SGnoCiYeH                 self.packet_mode_flush(tty.core());
818dfe53cf0SGnoCiYeH             }
81952da9a59SGnoCiYeH         }
82052da9a59SGnoCiYeH     }
82152da9a59SGnoCiYeH 
receive_char(&mut self, c: u8, tty: Arc<TtyCore>)82252da9a59SGnoCiYeH     pub fn receive_char(&mut self, c: u8, tty: Arc<TtyCore>) {
82352da9a59SGnoCiYeH         let termios = tty.core().termios();
82452da9a59SGnoCiYeH 
82552da9a59SGnoCiYeH         if termios.local_mode.contains(LocalMode::ECHO) {
82652da9a59SGnoCiYeH             if self.erasing {
82752da9a59SGnoCiYeH                 self.add_echo_byte(b'/');
82852da9a59SGnoCiYeH                 self.erasing = false;
82952da9a59SGnoCiYeH             }
83052da9a59SGnoCiYeH 
83152da9a59SGnoCiYeH             if self.canon_head == self.read_head {
83252da9a59SGnoCiYeH                 self.add_echo_byte(EchoOperation::Start.to_u8());
83352da9a59SGnoCiYeH                 self.add_echo_byte(EchoOperation::SetCanonCol.to_u8());
83452da9a59SGnoCiYeH             }
83552da9a59SGnoCiYeH 
83652da9a59SGnoCiYeH             self.echo_char(c, &termios);
83752da9a59SGnoCiYeH             self.commit_echoes(tty.clone());
83852da9a59SGnoCiYeH         }
83952da9a59SGnoCiYeH 
84052da9a59SGnoCiYeH         if c == 0o377 && tty.core().termios().input_mode.contains(InputMode::PARMRK) {
84152da9a59SGnoCiYeH             self.add_read_byte(c);
84252da9a59SGnoCiYeH         }
84352da9a59SGnoCiYeH         self.add_read_byte(c);
84452da9a59SGnoCiYeH     }
84552da9a59SGnoCiYeH 
echo_char(&mut self, c: u8, termios: &RwLockReadGuard<Termios>)84652da9a59SGnoCiYeH     pub fn echo_char(&mut self, c: u8, termios: &RwLockReadGuard<Termios>) {
84752da9a59SGnoCiYeH         if c == EchoOperation::Start.to_u8() {
84852da9a59SGnoCiYeH             self.add_echo_byte(EchoOperation::Start.to_u8());
84952da9a59SGnoCiYeH             self.add_echo_byte(EchoOperation::Start.to_u8());
85052da9a59SGnoCiYeH         } else {
85152da9a59SGnoCiYeH             if termios.local_mode.contains(LocalMode::ECHOCTL)
85252da9a59SGnoCiYeH                 && (c as char).is_control()
85352da9a59SGnoCiYeH                 && c != b'\t'
85452da9a59SGnoCiYeH             {
85552da9a59SGnoCiYeH                 self.add_echo_byte(EchoOperation::Start.to_u8());
85652da9a59SGnoCiYeH             }
85752da9a59SGnoCiYeH             self.add_echo_byte(c);
85852da9a59SGnoCiYeH         }
85952da9a59SGnoCiYeH     }
86052da9a59SGnoCiYeH 
echo_char_raw(&mut self, c: u8)86152da9a59SGnoCiYeH     pub fn echo_char_raw(&mut self, c: u8) {
86252da9a59SGnoCiYeH         if c == EchoOperation::Start.to_u8() {
86352da9a59SGnoCiYeH             self.add_echo_byte(EchoOperation::Start.to_u8());
86452da9a59SGnoCiYeH             self.add_echo_byte(EchoOperation::Start.to_u8());
86552da9a59SGnoCiYeH         } else {
86652da9a59SGnoCiYeH             self.add_echo_byte(c);
86752da9a59SGnoCiYeH         }
86852da9a59SGnoCiYeH     }
86952da9a59SGnoCiYeH 
87052da9a59SGnoCiYeH     /// ## 提交echobuf里的数据显示
commit_echoes(&mut self, tty: Arc<TtyCore>)87152da9a59SGnoCiYeH     pub fn commit_echoes(&mut self, tty: Arc<TtyCore>) {
87252da9a59SGnoCiYeH         let head = self.echo_head;
87352da9a59SGnoCiYeH         self.echo_mark = head;
87452da9a59SGnoCiYeH         let old = self.echo_commit - self.echo_tail;
87552da9a59SGnoCiYeH 
87652da9a59SGnoCiYeH         // 需要echo的字符个数
87752da9a59SGnoCiYeH         let nr = head - self.echo_tail;
87852da9a59SGnoCiYeH 
87952da9a59SGnoCiYeH         if nr < ECHO_COMMIT_WATERMARK || nr % ECHO_BLOCK > old % ECHO_BLOCK {
88052da9a59SGnoCiYeH             return;
88152da9a59SGnoCiYeH         }
88252da9a59SGnoCiYeH 
88352da9a59SGnoCiYeH         self.echo_commit = head;
88452da9a59SGnoCiYeH         let echoed = self.echoes(tty.clone());
88552da9a59SGnoCiYeH 
88652da9a59SGnoCiYeH         if echoed.is_ok() && echoed.unwrap() > 0 {
88752da9a59SGnoCiYeH             tty.flush_chars(tty.core());
88852da9a59SGnoCiYeH         }
88952da9a59SGnoCiYeH     }
89052da9a59SGnoCiYeH 
add_echo_byte(&mut self, c: u8)89152da9a59SGnoCiYeH     pub fn add_echo_byte(&mut self, c: u8) {
89252da9a59SGnoCiYeH         self.echo_buf[ntty_buf_mask(self.echo_head)] = c;
89352da9a59SGnoCiYeH         self.echo_head += 1;
89452da9a59SGnoCiYeH     }
89552da9a59SGnoCiYeH 
add_read_byte(&mut self, c: u8)89652da9a59SGnoCiYeH     pub fn add_read_byte(&mut self, c: u8) {
89752da9a59SGnoCiYeH         self.read_buf[ntty_buf_mask(self.read_head)] = c;
89852da9a59SGnoCiYeH         self.read_head += 1;
89952da9a59SGnoCiYeH     }
90052da9a59SGnoCiYeH 
90152da9a59SGnoCiYeH     /// ### 将read_buffer的部分值置0
90252da9a59SGnoCiYeH     ///
90352da9a59SGnoCiYeH     /// 只会在规范模式和禁用echo下执行
90452da9a59SGnoCiYeH     #[inline]
zero_buffer(&mut self, offset: usize, size: usize)90552da9a59SGnoCiYeH     pub fn zero_buffer(&mut self, offset: usize, size: usize) {
90652da9a59SGnoCiYeH         let offset = offset & (NTTY_BUFSIZE - 1);
90752da9a59SGnoCiYeH         if self.icanon && !self.echo {
90852da9a59SGnoCiYeH             let n = offset + size;
90952da9a59SGnoCiYeH             if n > NTTY_BUFSIZE {
91052da9a59SGnoCiYeH                 for c in &mut self.read_buf[offset..NTTY_BUFSIZE] {
91152da9a59SGnoCiYeH                     *c = 0
91252da9a59SGnoCiYeH                 }
91352da9a59SGnoCiYeH 
91452da9a59SGnoCiYeH                 for c in &mut self.read_buf[0..(n - NTTY_BUFSIZE)] {
91552da9a59SGnoCiYeH                     *c = 0
91652da9a59SGnoCiYeH                 }
91752da9a59SGnoCiYeH             } else {
91852da9a59SGnoCiYeH                 for c in &mut self.read_buf[offset..n] {
91952da9a59SGnoCiYeH                     *c = 0
92052da9a59SGnoCiYeH                 }
92152da9a59SGnoCiYeH             };
92252da9a59SGnoCiYeH         }
92352da9a59SGnoCiYeH     }
92452da9a59SGnoCiYeH 
92552da9a59SGnoCiYeH     /// ## 从ntty中拷贝数据
92652da9a59SGnoCiYeH     ///
92752da9a59SGnoCiYeH     /// ### 参数
92852da9a59SGnoCiYeH     ///
92952da9a59SGnoCiYeH     /// ### to: 存储数据
93052da9a59SGnoCiYeH     /// ### tail: 读取尾
ntty_copy( &mut self, to: &mut [u8], tail: usize, n: &mut usize, ) -> Result<(), SystemError>93152da9a59SGnoCiYeH     pub fn ntty_copy(
93252da9a59SGnoCiYeH         &mut self,
93352da9a59SGnoCiYeH         to: &mut [u8],
93452da9a59SGnoCiYeH         tail: usize,
93552da9a59SGnoCiYeH         n: &mut usize,
93652da9a59SGnoCiYeH     ) -> Result<(), SystemError> {
93752da9a59SGnoCiYeH         if to.len() < *n {
93852da9a59SGnoCiYeH             *n = to.len();
93952da9a59SGnoCiYeH             // return Err(SystemError::EINVAL);
94052da9a59SGnoCiYeH         }
94152da9a59SGnoCiYeH         if tail > NTTY_BUFSIZE {
94252da9a59SGnoCiYeH             return Err(SystemError::EINVAL);
94352da9a59SGnoCiYeH         }
94452da9a59SGnoCiYeH 
94552da9a59SGnoCiYeH         let size = NTTY_BUFSIZE - tail;
94652da9a59SGnoCiYeH 
94752da9a59SGnoCiYeH         if size < *n {
94852da9a59SGnoCiYeH             // 有一部分数据在头部,则先拷贝后面部分,再拷贝头部
94952da9a59SGnoCiYeH             // TODO: tty审计?
95052da9a59SGnoCiYeH             to[0..size].copy_from_slice(&self.read_buf[tail..(tail + size)]);
95152bcb59eSGnoCiYeH             to[size..(*n)].copy_from_slice(&self.read_buf[0..(*n - size)]);
95252da9a59SGnoCiYeH         } else {
95352da9a59SGnoCiYeH             to[..*n].copy_from_slice(&self.read_buf[tail..(tail + *n)])
95452da9a59SGnoCiYeH         }
95552da9a59SGnoCiYeH 
95652da9a59SGnoCiYeH         self.zero_buffer(tail, *n);
95752da9a59SGnoCiYeH 
95852da9a59SGnoCiYeH         Ok(())
95952da9a59SGnoCiYeH     }
96052da9a59SGnoCiYeH 
96152da9a59SGnoCiYeH     /// ## 规范模式下跳过EOF
canon_skip_eof(&mut self)96252da9a59SGnoCiYeH     pub fn canon_skip_eof(&mut self) {
96352da9a59SGnoCiYeH         // 没有数据
96452da9a59SGnoCiYeH         if self.read_tail == self.canon_head {
96552da9a59SGnoCiYeH             return;
96652da9a59SGnoCiYeH         }
96752da9a59SGnoCiYeH 
96852da9a59SGnoCiYeH         let tail = self.read_tail & (NTTY_BUFSIZE - 1);
96952da9a59SGnoCiYeH 
97052da9a59SGnoCiYeH         // 查看read_flags是否读取位置为特殊字符
97152da9a59SGnoCiYeH         if !self.read_flags.get(tail).unwrap() {
97252da9a59SGnoCiYeH             return;
97352da9a59SGnoCiYeH         }
97452da9a59SGnoCiYeH 
97552da9a59SGnoCiYeH         // 确保读取位置是'\0'字符
97652da9a59SGnoCiYeH         if self.read_buf[tail] != ControlCharIndex::DISABLE_CHAR {
97752da9a59SGnoCiYeH             return;
97852da9a59SGnoCiYeH         }
97952da9a59SGnoCiYeH 
98052da9a59SGnoCiYeH         // 处理该字符,将read_flagsw该位清除
98152da9a59SGnoCiYeH         self.read_flags.set(tail, false);
98252da9a59SGnoCiYeH         // 读取位置+1,即跳过该字符不做处理
98352da9a59SGnoCiYeH         self.read_tail += 1;
98452da9a59SGnoCiYeH     }
98552da9a59SGnoCiYeH 
98652da9a59SGnoCiYeH     /// ## 在规范模式(canonical mode)下从读缓冲中复制一行
98752da9a59SGnoCiYeH     ///
98852da9a59SGnoCiYeH     /// 一次只拷贝一行
98952da9a59SGnoCiYeH     ///
99052da9a59SGnoCiYeH     /// ## 参数
99152da9a59SGnoCiYeH     /// ### dst: 存放数据
99252da9a59SGnoCiYeH     /// ### nr: 需要拷贝的数据大小
99352da9a59SGnoCiYeH     ///
99452da9a59SGnoCiYeH     /// ## 返回值
99552da9a59SGnoCiYeH     /// ### true: 表示一行未结束并且还有数据可读
99652da9a59SGnoCiYeH     /// ### false: 一行已结束或者没有数据可读
canon_copy_from_read_buf( &mut self, dst: &mut [u8], nr: &mut usize, offset: &mut usize, ) -> Result<bool, SystemError>99752da9a59SGnoCiYeH     pub fn canon_copy_from_read_buf(
99852da9a59SGnoCiYeH         &mut self,
99952da9a59SGnoCiYeH         dst: &mut [u8],
100052da9a59SGnoCiYeH         nr: &mut usize,
100152da9a59SGnoCiYeH         offset: &mut usize,
100252da9a59SGnoCiYeH     ) -> Result<bool, SystemError> {
100352da9a59SGnoCiYeH         if *nr == 0 {
100452da9a59SGnoCiYeH             return Ok(false);
100552da9a59SGnoCiYeH         }
100652da9a59SGnoCiYeH 
100752da9a59SGnoCiYeH         let canon_head = self.canon_head;
100852da9a59SGnoCiYeH 
100952da9a59SGnoCiYeH         // 取得能够读到的字符数,即canon_head - self.read_tail和nr最小值
101052da9a59SGnoCiYeH         let mut n = (*nr).min(canon_head - self.read_tail);
101152da9a59SGnoCiYeH 
101252da9a59SGnoCiYeH         // 获得读尾index
101352da9a59SGnoCiYeH         let tail = self.read_tail & (NTTY_BUFSIZE - 1);
101452da9a59SGnoCiYeH 
101552da9a59SGnoCiYeH         // 避免越界,这个size才是实际读取大小
101652da9a59SGnoCiYeH         let size = if tail + n > NTTY_BUFSIZE {
101752da9a59SGnoCiYeH             NTTY_BUFSIZE
101852da9a59SGnoCiYeH         } else {
101952bcb59eSGnoCiYeH             tail + n
102052da9a59SGnoCiYeH         };
102152da9a59SGnoCiYeH 
102252da9a59SGnoCiYeH         // 找到eol的坐标
102352da9a59SGnoCiYeH         let tmp = self.read_flags.next_index(tail);
102452da9a59SGnoCiYeH         // 找到的话即为坐标,未找到的话即为NTTY_BUFSIZE
1025b5b571e0SLoGin         let mut eol = if let Some(tmp) = tmp { tmp } else { size };
102652da9a59SGnoCiYeH         if eol > size {
102752da9a59SGnoCiYeH             eol = size
102852da9a59SGnoCiYeH         }
102952da9a59SGnoCiYeH 
103052da9a59SGnoCiYeH         // 是否需要绕回缓冲区头部
103152da9a59SGnoCiYeH         let more = n - (size - tail);
103252da9a59SGnoCiYeH 
103352da9a59SGnoCiYeH         // 是否找到eol
103452da9a59SGnoCiYeH         let found = if eol == NTTY_BUFSIZE && more > 0 {
103552da9a59SGnoCiYeH             // 需要返回头部
103652da9a59SGnoCiYeH             let ret = self.read_flags.first_index();
1037b5b571e0SLoGin             if let Some(tmp) = ret {
103852da9a59SGnoCiYeH                 // 在头部范围内找到eol
103952da9a59SGnoCiYeH                 if tmp < more {
104052da9a59SGnoCiYeH                     eol = tmp;
104152da9a59SGnoCiYeH                 }
104252da9a59SGnoCiYeH             } else {
104352da9a59SGnoCiYeH                 eol = more;
104452da9a59SGnoCiYeH             }
104552da9a59SGnoCiYeH             eol != more
104652da9a59SGnoCiYeH         } else {
104752da9a59SGnoCiYeH             // 不需要返回头部
104852da9a59SGnoCiYeH             eol != size
104952da9a59SGnoCiYeH         };
105052da9a59SGnoCiYeH 
105152da9a59SGnoCiYeH         n = eol - tail;
105252da9a59SGnoCiYeH         if n > NTTY_BUFSIZE {
105352da9a59SGnoCiYeH             // 减法溢出则加上BUFSIZE即可限制在0-NTTY_BUFSIZE内
105452da9a59SGnoCiYeH             n += NTTY_BUFSIZE;
105552da9a59SGnoCiYeH         }
105652da9a59SGnoCiYeH 
105752da9a59SGnoCiYeH         // 规范模式下实际扫描过的字符数,需要将eol计算在内
105852da9a59SGnoCiYeH         let count = if found { n + 1 } else { n };
105952da9a59SGnoCiYeH 
106052da9a59SGnoCiYeH         // 表示这一行未结束
106152da9a59SGnoCiYeH         if !found || self.read_at(eol) != ControlCharIndex::DISABLE_CHAR {
106252da9a59SGnoCiYeH             n = count;
106352da9a59SGnoCiYeH         }
106452da9a59SGnoCiYeH 
106552da9a59SGnoCiYeH         self.ntty_copy(&mut dst[*offset..], tail, &mut n)?;
106652da9a59SGnoCiYeH         *nr -= n;
106752da9a59SGnoCiYeH         *offset += n;
106852da9a59SGnoCiYeH 
106952da9a59SGnoCiYeH         if found {
107052da9a59SGnoCiYeH             self.read_flags.set(eol, false);
107152da9a59SGnoCiYeH         }
107252da9a59SGnoCiYeH 
107352da9a59SGnoCiYeH         self.read_tail += count;
107452da9a59SGnoCiYeH 
107552da9a59SGnoCiYeH         if found {
107652da9a59SGnoCiYeH             if !self.pushing {
107752da9a59SGnoCiYeH                 self.line_start = self.read_tail;
107852da9a59SGnoCiYeH             } else {
107952da9a59SGnoCiYeH                 self.pushing = false;
108052da9a59SGnoCiYeH             }
108152da9a59SGnoCiYeH 
108252da9a59SGnoCiYeH             // todo: 审计?
108352da9a59SGnoCiYeH             return Ok(false);
108452da9a59SGnoCiYeH         }
108552da9a59SGnoCiYeH 
108652da9a59SGnoCiYeH         // 这里是表示没有找到eol,根据是否还有数据可读返回
108752da9a59SGnoCiYeH         Ok(self.read_tail != canon_head)
108852da9a59SGnoCiYeH     }
108952da9a59SGnoCiYeH 
109052da9a59SGnoCiYeH     /// ## 根据终端的模式和输入缓冲区中的数据量,判断是否可读字符
input_available(&self, termios: RwLockReadGuard<Termios>, poll: bool) -> bool109152da9a59SGnoCiYeH     pub fn input_available(&self, termios: RwLockReadGuard<Termios>, poll: bool) -> bool {
109252da9a59SGnoCiYeH         // 计算最小字符数
109352da9a59SGnoCiYeH         let amt = if poll
109452da9a59SGnoCiYeH             && termios.control_characters[ControlCharIndex::VTIME] as u32 == 0
109552da9a59SGnoCiYeH             && termios.control_characters[ControlCharIndex::VMIN] as u32 != 0
109652da9a59SGnoCiYeH         {
109752da9a59SGnoCiYeH             termios.control_characters[ControlCharIndex::VMIN] as usize
109852da9a59SGnoCiYeH         } else {
109952da9a59SGnoCiYeH             1
110052da9a59SGnoCiYeH         };
110152da9a59SGnoCiYeH 
110252da9a59SGnoCiYeH         // 规范模式且非拓展
110352da9a59SGnoCiYeH         if self.icanon && !termios.local_mode.contains(LocalMode::EXTPROC) {
110452da9a59SGnoCiYeH             return self.canon_head != self.read_tail;
110552da9a59SGnoCiYeH         } else {
110652da9a59SGnoCiYeH             return (self.commit_head - self.read_tail) >= amt;
110752da9a59SGnoCiYeH         }
110852da9a59SGnoCiYeH     }
110952da9a59SGnoCiYeH 
111052da9a59SGnoCiYeH     /// ## 非规范模式下从read_buf读取数据
111152da9a59SGnoCiYeH     ///
111252da9a59SGnoCiYeH     /// ## 参数
111352da9a59SGnoCiYeH     /// ### termios: tty对应的termioss读锁守卫
111452da9a59SGnoCiYeH     /// ### dst: 存储读取数据
111552da9a59SGnoCiYeH     /// ### nr: 读取长度
111652da9a59SGnoCiYeH     ///
111752da9a59SGnoCiYeH     /// ## 返回值
111852da9a59SGnoCiYeH     /// ### true: 还有更多数据可读
111952da9a59SGnoCiYeH     /// ### false: 无更多数据可读
copy_from_read_buf( &mut self, termios: RwLockReadGuard<Termios>, dst: &mut [u8], nr: &mut usize, offset: &mut usize, ) -> Result<bool, SystemError>112052da9a59SGnoCiYeH     pub fn copy_from_read_buf(
112152da9a59SGnoCiYeH         &mut self,
112252da9a59SGnoCiYeH         termios: RwLockReadGuard<Termios>,
112352da9a59SGnoCiYeH         dst: &mut [u8],
112452da9a59SGnoCiYeH         nr: &mut usize,
112552da9a59SGnoCiYeH         offset: &mut usize,
112652da9a59SGnoCiYeH     ) -> Result<bool, SystemError> {
112752da9a59SGnoCiYeH         let head = self.commit_head;
112852da9a59SGnoCiYeH         let tail = self.read_tail & (NTTY_BUFSIZE - 1);
112952da9a59SGnoCiYeH 
113052da9a59SGnoCiYeH         // 计算出可读的字符数
113152bcb59eSGnoCiYeH         let mut n = (NTTY_BUFSIZE - tail).min(head - self.read_tail);
113252da9a59SGnoCiYeH         n = n.min(*nr);
113352da9a59SGnoCiYeH 
113452da9a59SGnoCiYeH         if n > 0 {
113552da9a59SGnoCiYeH             // 拷贝数据
113652da9a59SGnoCiYeH             self.ntty_copy(&mut dst[*offset..], tail, &mut n)?;
113752da9a59SGnoCiYeH             // todo:审计?
113852da9a59SGnoCiYeH             self.read_tail += n;
113952da9a59SGnoCiYeH 
114052da9a59SGnoCiYeH             // 是否只读取了eof
114152da9a59SGnoCiYeH             let eof =
114252da9a59SGnoCiYeH                 n == 1 && self.read_buf[tail] == termios.control_characters[ControlCharIndex::VEOF];
114352da9a59SGnoCiYeH 
114452da9a59SGnoCiYeH             if termios.local_mode.contains(LocalMode::EXTPROC)
114552da9a59SGnoCiYeH                 && self.icanon
114652da9a59SGnoCiYeH                 && eof
114752da9a59SGnoCiYeH                 && head == self.read_tail
114852da9a59SGnoCiYeH             {
114952da9a59SGnoCiYeH                 return Ok(false);
115052da9a59SGnoCiYeH             }
115152da9a59SGnoCiYeH 
115252da9a59SGnoCiYeH             *nr -= n;
115352da9a59SGnoCiYeH             *offset += n;
115452da9a59SGnoCiYeH 
115552da9a59SGnoCiYeH             return Ok(head != self.read_tail);
115652da9a59SGnoCiYeH         }
115752da9a59SGnoCiYeH 
115852da9a59SGnoCiYeH         Ok(false)
115952da9a59SGnoCiYeH     }
116052da9a59SGnoCiYeH 
116152da9a59SGnoCiYeH     /// ## 用于处理带有 OPOST(Output Post-processing)标志的输出块的函数
116252da9a59SGnoCiYeH     /// OPOST 是 POSIX 终端驱动器标志之一,用于指定在写入终端设备之前对输出数据进行一些后期处理。
process_output_block( &mut self, core: &TtyCoreData, termios: RwLockReadGuard<Termios>, buf: &[u8], nr: usize, ) -> Result<usize, SystemError>116352da9a59SGnoCiYeH     pub fn process_output_block(
116452da9a59SGnoCiYeH         &mut self,
116552da9a59SGnoCiYeH         core: &TtyCoreData,
116652da9a59SGnoCiYeH         termios: RwLockReadGuard<Termios>,
116752da9a59SGnoCiYeH         buf: &[u8],
116852da9a59SGnoCiYeH         nr: usize,
116952da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
117052da9a59SGnoCiYeH         let mut nr = nr;
11719365e801SGnoCiYeH         let tty = self.tty.upgrade().unwrap();
117252da9a59SGnoCiYeH         let space = tty.write_room(tty.core());
117352da9a59SGnoCiYeH 
117452da9a59SGnoCiYeH         // 如果读取数量大于了可用空间,则取最小的为真正的写入数量
117552da9a59SGnoCiYeH         if nr > space {
117652da9a59SGnoCiYeH             nr = space
117752da9a59SGnoCiYeH         }
117852da9a59SGnoCiYeH 
117952da9a59SGnoCiYeH         let mut cnt = 0;
1180b5b571e0SLoGin         for (i, c) in buf.iter().enumerate().take(nr) {
118152da9a59SGnoCiYeH             cnt = i;
1182b5b571e0SLoGin             let c = *c;
118352da9a59SGnoCiYeH             if c as usize == 8 {
118452da9a59SGnoCiYeH                 // 表示退格
118552da9a59SGnoCiYeH                 if self.cursor_column > 0 {
118652da9a59SGnoCiYeH                     self.cursor_column -= 1;
118752da9a59SGnoCiYeH                 }
118852da9a59SGnoCiYeH                 continue;
118952da9a59SGnoCiYeH             }
119052da9a59SGnoCiYeH             match c as char {
119152da9a59SGnoCiYeH                 '\n' => {
119252da9a59SGnoCiYeH                     if termios.output_mode.contains(OutputMode::ONLRET) {
119352da9a59SGnoCiYeH                         // 将回车映射为\n,即将\n换为回车
119452da9a59SGnoCiYeH                         self.cursor_column = 0;
119552da9a59SGnoCiYeH                     }
119652da9a59SGnoCiYeH                     if termios.output_mode.contains(OutputMode::ONLCR) {
119752da9a59SGnoCiYeH                         // 输出时将\n换为\r\n
119852da9a59SGnoCiYeH                         break;
119952da9a59SGnoCiYeH                     }
120052da9a59SGnoCiYeH 
120152da9a59SGnoCiYeH                     self.canon_cursor_column = self.cursor_column;
120252da9a59SGnoCiYeH                 }
120352da9a59SGnoCiYeH                 '\r' => {
120452da9a59SGnoCiYeH                     if termios.output_mode.contains(OutputMode::ONOCR) && self.cursor_column == 0 {
120552da9a59SGnoCiYeH                         // 光标已经在第0列,则不输出回车符
120652da9a59SGnoCiYeH                         break;
120752da9a59SGnoCiYeH                     }
120852da9a59SGnoCiYeH 
120952da9a59SGnoCiYeH                     if termios.output_mode.contains(OutputMode::OCRNL) {
121052da9a59SGnoCiYeH                         break;
121152da9a59SGnoCiYeH                     }
121252da9a59SGnoCiYeH                     self.canon_cursor_column = self.cursor_column;
121352da9a59SGnoCiYeH                 }
121452da9a59SGnoCiYeH                 '\t' => {
121552da9a59SGnoCiYeH                     break;
121652da9a59SGnoCiYeH                 }
121752da9a59SGnoCiYeH                 _ => {
121852da9a59SGnoCiYeH                     // 判断是否为控制字符
121952da9a59SGnoCiYeH                     if !(c as char).is_control() {
122052da9a59SGnoCiYeH                         if termios.output_mode.contains(OutputMode::OLCUC) {
122152da9a59SGnoCiYeH                             break;
122252da9a59SGnoCiYeH                         }
122352da9a59SGnoCiYeH 
122452da9a59SGnoCiYeH                         // 判断是否为utf8模式下的连续字符
122552da9a59SGnoCiYeH                         if !(termios.input_mode.contains(InputMode::IUTF8)
122652da9a59SGnoCiYeH                             && (c as usize) & 0xc0 == 0x80)
122752da9a59SGnoCiYeH                         {
122852da9a59SGnoCiYeH                             self.cursor_column += 1;
122952da9a59SGnoCiYeH                         }
123052da9a59SGnoCiYeH                     }
123152da9a59SGnoCiYeH                 }
123252da9a59SGnoCiYeH             }
123352da9a59SGnoCiYeH         }
123452da9a59SGnoCiYeH 
123552da9a59SGnoCiYeH         drop(termios);
123652da9a59SGnoCiYeH         return tty.write(core, buf, cnt);
123752da9a59SGnoCiYeH     }
123852da9a59SGnoCiYeH 
123952da9a59SGnoCiYeH     /// ## 处理回显
process_echoes(&mut self, tty: Arc<TtyCore>)124052da9a59SGnoCiYeH     pub fn process_echoes(&mut self, tty: Arc<TtyCore>) {
124152da9a59SGnoCiYeH         if self.echo_mark == self.echo_tail {
124252da9a59SGnoCiYeH             return;
124352da9a59SGnoCiYeH         }
124452da9a59SGnoCiYeH         self.echo_commit = self.echo_mark;
124552da9a59SGnoCiYeH         let echoed = self.echoes(tty.clone());
124652da9a59SGnoCiYeH 
124752da9a59SGnoCiYeH         if echoed.is_ok() && echoed.unwrap() > 0 {
1248b5b571e0SLoGin             tty.flush_chars(tty.core());
124952da9a59SGnoCiYeH         }
125052da9a59SGnoCiYeH     }
125152da9a59SGnoCiYeH 
125252bcb59eSGnoCiYeH     #[inline(never)]
echoes(&mut self, tty: Arc<TtyCore>) -> Result<usize, SystemError>125352da9a59SGnoCiYeH     pub fn echoes(&mut self, tty: Arc<TtyCore>) -> Result<usize, SystemError> {
125452da9a59SGnoCiYeH         let mut space = tty.write_room(tty.core());
125552da9a59SGnoCiYeH         let ospace = space;
125652da9a59SGnoCiYeH         let termios = tty.core().termios();
125752da9a59SGnoCiYeH         let core = tty.core();
125852da9a59SGnoCiYeH         let mut tail = self.echo_tail;
125952da9a59SGnoCiYeH 
126052da9a59SGnoCiYeH         while ntty_buf_mask(self.echo_commit) != ntty_buf_mask(tail) {
126152da9a59SGnoCiYeH             let c = self.echo_buf[ntty_buf_mask(tail)];
126252da9a59SGnoCiYeH 
126352da9a59SGnoCiYeH             if EchoOperation::from_u8(c) == EchoOperation::Start {
126452da9a59SGnoCiYeH                 if ntty_buf_mask(self.echo_commit) == ntty_buf_mask(tail + 1) {
126552da9a59SGnoCiYeH                     self.echo_tail = tail;
126652da9a59SGnoCiYeH                     return Ok(ospace - space);
126752da9a59SGnoCiYeH                 }
126852da9a59SGnoCiYeH 
126952da9a59SGnoCiYeH                 // 获取到start,之后取第一个作为op
127052da9a59SGnoCiYeH                 let op = EchoOperation::from_u8(self.echo_buf[ntty_buf_mask(tail + 1)]);
127152da9a59SGnoCiYeH 
127252da9a59SGnoCiYeH                 match op {
127352da9a59SGnoCiYeH                     EchoOperation::Start => {
127452da9a59SGnoCiYeH                         if space == 0 {
127552da9a59SGnoCiYeH                             break;
127652da9a59SGnoCiYeH                         }
127752da9a59SGnoCiYeH 
127852da9a59SGnoCiYeH                         if tty
127952da9a59SGnoCiYeH                             .put_char(tty.core(), EchoOperation::Start.to_u8())
128052da9a59SGnoCiYeH                             .is_err()
128152da9a59SGnoCiYeH                         {
128252da9a59SGnoCiYeH                             tty.write(core, &[EchoOperation::Start.to_u8()], 1)?;
128352da9a59SGnoCiYeH                         }
128452da9a59SGnoCiYeH 
128552da9a59SGnoCiYeH                         self.cursor_column += 1;
128652da9a59SGnoCiYeH                         space -= 1;
128752da9a59SGnoCiYeH                         tail += 2;
128852da9a59SGnoCiYeH                     }
128952da9a59SGnoCiYeH                     EchoOperation::MoveBackCol => {
129052da9a59SGnoCiYeH                         if self.cursor_column > 0 {
129152da9a59SGnoCiYeH                             self.cursor_column -= 1;
129252da9a59SGnoCiYeH                         }
129352da9a59SGnoCiYeH                         tail += 2;
129452da9a59SGnoCiYeH                     }
129552da9a59SGnoCiYeH                     EchoOperation::SetCanonCol => {
129652da9a59SGnoCiYeH                         self.canon_cursor_column = self.cursor_column;
129752da9a59SGnoCiYeH                         tail += 2;
129852da9a59SGnoCiYeH                     }
129952da9a59SGnoCiYeH                     EchoOperation::EraseTab => {
130052da9a59SGnoCiYeH                         if ntty_buf_mask(self.echo_commit) == ntty_buf_mask(tail + 2) {
130152da9a59SGnoCiYeH                             self.echo_tail = tail;
130252da9a59SGnoCiYeH                             return Ok(ospace - space);
130352da9a59SGnoCiYeH                         }
130452da9a59SGnoCiYeH 
130552da9a59SGnoCiYeH                         // 要擦除的制表符所占用的列数
130652da9a59SGnoCiYeH                         let mut char_num = self.echo_buf[ntty_buf_mask(tail + 2)] as usize;
130752da9a59SGnoCiYeH 
130852da9a59SGnoCiYeH                         /*
130952da9a59SGnoCiYeH                            如果 num_chars 的最高位(0x80)未设置,
131052da9a59SGnoCiYeH                            表示这是从输入的起始位置而不是从先前的制表符开始计算的列数。
131152da9a59SGnoCiYeH                            在这种情况下,将 num_chars 与 ldata->canon_column 相加,否则,列数就是正常的制表符列数。
131252da9a59SGnoCiYeH                         */
131352da9a59SGnoCiYeH                         if char_num & 0x80 == 0 {
131452da9a59SGnoCiYeH                             char_num += self.canon_cursor_column as usize;
131552da9a59SGnoCiYeH                         }
131652da9a59SGnoCiYeH 
131752da9a59SGnoCiYeH                         // 计算要回退的列数,即制表符宽度减去实际占用的列数
131852da9a59SGnoCiYeH                         let mut num_bs = 8 - (char_num & 7);
131952da9a59SGnoCiYeH                         if num_bs > space {
132052da9a59SGnoCiYeH                             // 表示左边没有足够空间回退
132152da9a59SGnoCiYeH                             break;
132252da9a59SGnoCiYeH                         }
132352da9a59SGnoCiYeH 
132452da9a59SGnoCiYeH                         space -= num_bs;
132552da9a59SGnoCiYeH                         while num_bs != 0 {
132652da9a59SGnoCiYeH                             num_bs -= 1;
132752da9a59SGnoCiYeH                             // 8 => '\b'
132852da9a59SGnoCiYeH                             if tty.put_char(tty.core(), 8).is_err() {
132952da9a59SGnoCiYeH                                 tty.write(core, &[8], 1)?;
133052da9a59SGnoCiYeH                             }
133152da9a59SGnoCiYeH 
133252da9a59SGnoCiYeH                             if self.cursor_column > 0 {
133352da9a59SGnoCiYeH                                 self.cursor_column -= 1;
133452da9a59SGnoCiYeH                             }
133552da9a59SGnoCiYeH                         }
133652da9a59SGnoCiYeH 
133752da9a59SGnoCiYeH                         // 已经读取了 tail tail+1 tail+2,所以这里偏移加3
133852da9a59SGnoCiYeH                         tail += 3;
133952da9a59SGnoCiYeH                     }
134052da9a59SGnoCiYeH                     EchoOperation::Undefined(ch) => {
134152da9a59SGnoCiYeH                         match ch {
134252da9a59SGnoCiYeH                             8 => {
134352da9a59SGnoCiYeH                                 if tty.put_char(tty.core(), 8).is_err() {
134452da9a59SGnoCiYeH                                     tty.write(core, &[8], 1)?;
134552da9a59SGnoCiYeH                                 }
1346b5b571e0SLoGin                                 if tty.put_char(tty.core(), b' ').is_err() {
1347bd70d2d1SLoGin                                     tty.write(core, b" ", 1)?;
134852da9a59SGnoCiYeH                                 }
134952da9a59SGnoCiYeH                                 self.cursor_column -= 1;
135052da9a59SGnoCiYeH                                 space -= 1;
135152da9a59SGnoCiYeH                                 tail += 1;
135252da9a59SGnoCiYeH                             }
135352da9a59SGnoCiYeH                             _ => {
135452da9a59SGnoCiYeH                                 // 不是特殊字节码,则表示控制字符 例如 ^C
135552da9a59SGnoCiYeH                                 if space < 2 {
135652da9a59SGnoCiYeH                                     break;
135752da9a59SGnoCiYeH                                 }
135852da9a59SGnoCiYeH 
135952da9a59SGnoCiYeH                                 if tty.put_char(tty.core(), b'^').is_err() {
1360bd70d2d1SLoGin                                     tty.write(core, b"^", 1)?;
136152da9a59SGnoCiYeH                                 }
136252da9a59SGnoCiYeH 
136352da9a59SGnoCiYeH                                 if tty.put_char(tty.core(), ch ^ 0o100).is_err() {
136452da9a59SGnoCiYeH                                     tty.write(core, &[ch ^ 0o100], 1)?;
136552da9a59SGnoCiYeH                                 }
136652da9a59SGnoCiYeH 
136752da9a59SGnoCiYeH                                 self.cursor_column += 2;
136852da9a59SGnoCiYeH                                 space -= 2;
136952da9a59SGnoCiYeH                                 tail += 2;
137052da9a59SGnoCiYeH                             }
137152da9a59SGnoCiYeH                         }
137252da9a59SGnoCiYeH                     }
137352da9a59SGnoCiYeH                 }
137452da9a59SGnoCiYeH             } else {
137552da9a59SGnoCiYeH                 if termios.output_mode.contains(OutputMode::OPOST) {
137652da9a59SGnoCiYeH                     let ret = self.do_output_char(tty.clone(), c, space);
137752da9a59SGnoCiYeH 
137852da9a59SGnoCiYeH                     if ret.is_err() {
137952da9a59SGnoCiYeH                         break;
138052da9a59SGnoCiYeH                     }
138152da9a59SGnoCiYeH                     space -= ret.unwrap();
138252da9a59SGnoCiYeH                 } else {
138352da9a59SGnoCiYeH                     if space == 0 {
138452da9a59SGnoCiYeH                         break;
138552da9a59SGnoCiYeH                     }
138652da9a59SGnoCiYeH 
138752da9a59SGnoCiYeH                     if tty.put_char(tty.core(), c).is_err() {
138852da9a59SGnoCiYeH                         tty.write(core, &[c], 1)?;
138952da9a59SGnoCiYeH                     }
139052da9a59SGnoCiYeH                     space -= 1;
139152da9a59SGnoCiYeH                 }
139252da9a59SGnoCiYeH                 tail += 1;
139352da9a59SGnoCiYeH             }
139452da9a59SGnoCiYeH         }
139552da9a59SGnoCiYeH 
139652da9a59SGnoCiYeH         // 如果回显缓冲区接近满(在下一次提交之前可能会发生回显溢出的情况),则丢弃足够的尾部数据以防止随后的溢出。
139752da9a59SGnoCiYeH         while self.echo_commit > tail && self.echo_commit - tail >= ECHO_DISCARD_WATERMARK {
139852da9a59SGnoCiYeH             if self.echo_buf[ntty_buf_mask(tail)] == EchoOperation::Start.to_u8() {
139952da9a59SGnoCiYeH                 if self.echo_buf[ntty_buf_mask(tail + 1)] == EchoOperation::EraseTab.to_u8() {
140052da9a59SGnoCiYeH                     tail += 3;
140152da9a59SGnoCiYeH                 } else {
140252da9a59SGnoCiYeH                     tail += 2;
140352da9a59SGnoCiYeH                 }
140452da9a59SGnoCiYeH             } else {
140552da9a59SGnoCiYeH                 tail += 1;
140652da9a59SGnoCiYeH             }
140752da9a59SGnoCiYeH         }
140852da9a59SGnoCiYeH 
140952da9a59SGnoCiYeH         self.echo_tail = tail;
141052da9a59SGnoCiYeH         return Ok(ospace - space);
141152da9a59SGnoCiYeH     }
141252da9a59SGnoCiYeH 
141352da9a59SGnoCiYeH     /// ## 处理输出字符(带有 OPOST 处理)
process_output(&mut self, tty: Arc<TtyCore>, c: u8) -> bool141452da9a59SGnoCiYeH     pub fn process_output(&mut self, tty: Arc<TtyCore>, c: u8) -> bool {
141552da9a59SGnoCiYeH         let space = tty.write_room(tty.core());
141652da9a59SGnoCiYeH 
141752da9a59SGnoCiYeH         if self.do_output_char(tty, c, space).is_err() {
141852da9a59SGnoCiYeH             return false;
141952da9a59SGnoCiYeH         }
142052da9a59SGnoCiYeH 
142152da9a59SGnoCiYeH         true
142252da9a59SGnoCiYeH     }
142352da9a59SGnoCiYeH 
142452da9a59SGnoCiYeH     // ## 设置带有 OPOST 处理的tty输出一个字符
do_output_char( &mut self, tty: Arc<TtyCore>, c: u8, space: usize, ) -> Result<usize, SystemError>142552da9a59SGnoCiYeH     pub fn do_output_char(
142652da9a59SGnoCiYeH         &mut self,
142752da9a59SGnoCiYeH         tty: Arc<TtyCore>,
142852da9a59SGnoCiYeH         c: u8,
142952da9a59SGnoCiYeH         space: usize,
143052da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
143152da9a59SGnoCiYeH         if space == 0 {
143252da9a59SGnoCiYeH             return Err(SystemError::ENOBUFS);
143352da9a59SGnoCiYeH         }
143452da9a59SGnoCiYeH 
143552da9a59SGnoCiYeH         let termios = tty.core().termios();
143652da9a59SGnoCiYeH         let core = tty.core();
143752da9a59SGnoCiYeH         let mut c = c;
143852da9a59SGnoCiYeH         if c as usize == 8 {
143952da9a59SGnoCiYeH             // 表示退格
144052da9a59SGnoCiYeH             if self.cursor_column > 0 {
144152da9a59SGnoCiYeH                 self.cursor_column -= 1;
144252da9a59SGnoCiYeH             }
144352da9a59SGnoCiYeH             if tty.put_char(tty.core(), c).is_err() {
144452da9a59SGnoCiYeH                 tty.write(core, &[c], 1)?;
144552da9a59SGnoCiYeH             }
144652da9a59SGnoCiYeH             return Ok(1);
144752da9a59SGnoCiYeH         }
144852da9a59SGnoCiYeH         match c as char {
144952da9a59SGnoCiYeH             '\n' => {
145052da9a59SGnoCiYeH                 if termios.output_mode.contains(OutputMode::ONLRET) {
145152da9a59SGnoCiYeH                     // 回车符
145252da9a59SGnoCiYeH                     self.cursor_column = 0;
145352da9a59SGnoCiYeH                 }
145452da9a59SGnoCiYeH                 if termios.output_mode.contains(OutputMode::ONLCR) {
145552da9a59SGnoCiYeH                     // 映射为“\r\n”
145652da9a59SGnoCiYeH                     if space < 2 {
145752da9a59SGnoCiYeH                         return Err(SystemError::ENOBUFS);
145852da9a59SGnoCiYeH                     }
145952da9a59SGnoCiYeH                     self.cursor_column = 0;
146052da9a59SGnoCiYeH                     self.canon_cursor_column = 0;
146152da9a59SGnoCiYeH 
146252da9a59SGnoCiYeH                     // 通过驱动写入
146352da9a59SGnoCiYeH                     tty.write(core, "\r\n".as_bytes(), 2)?;
146452da9a59SGnoCiYeH                     return Ok(2);
146552da9a59SGnoCiYeH                 }
146652da9a59SGnoCiYeH 
146752da9a59SGnoCiYeH                 self.canon_cursor_column = self.cursor_column;
146852da9a59SGnoCiYeH             }
146952da9a59SGnoCiYeH             '\r' => {
147052da9a59SGnoCiYeH                 if termios.output_mode.contains(OutputMode::ONOCR) && self.cursor_column == 0 {
147152da9a59SGnoCiYeH                     // 光标已经在第0列,则不输出回车符
147252da9a59SGnoCiYeH                     return Ok(0);
147352da9a59SGnoCiYeH                 }
147452da9a59SGnoCiYeH 
147552da9a59SGnoCiYeH                 if termios.output_mode.contains(OutputMode::OCRNL) {
147652da9a59SGnoCiYeH                     // 输出的\r映射为\n
147752da9a59SGnoCiYeH                     c = b'\n';
147852da9a59SGnoCiYeH                     if termios.output_mode.contains(OutputMode::ONLRET) {
147952da9a59SGnoCiYeH                         // \r映射为\n,但是保留\r特性
148052da9a59SGnoCiYeH                         self.cursor_column = 0;
148152da9a59SGnoCiYeH                         self.canon_cursor_column = 0;
148252da9a59SGnoCiYeH                     }
148352da9a59SGnoCiYeH                 } else {
148452da9a59SGnoCiYeH                     self.cursor_column = 0;
148552da9a59SGnoCiYeH                     self.canon_cursor_column = 0;
148652da9a59SGnoCiYeH                 }
148752da9a59SGnoCiYeH             }
148852da9a59SGnoCiYeH             '\t' => {
148952da9a59SGnoCiYeH                 // 计算输出一个\t需要的空间
149052da9a59SGnoCiYeH                 let spaces = 8 - (self.cursor_column & 7) as usize;
1491b5b571e0SLoGin                 if termios.output_mode.contains(OutputMode::TABDLY)
1492b5b571e0SLoGin                     && OutputMode::TABDLY.bits() == OutputMode::XTABS.bits()
1493b5b571e0SLoGin                 {
149452da9a59SGnoCiYeH                     // 配置的tab选项是真正输出空格到驱动
149552da9a59SGnoCiYeH                     if space < spaces {
149652da9a59SGnoCiYeH                         // 空间不够
149752da9a59SGnoCiYeH                         return Err(SystemError::ENOBUFS);
149852da9a59SGnoCiYeH                     }
149952da9a59SGnoCiYeH                     self.cursor_column += spaces as u32;
150052da9a59SGnoCiYeH                     // 写入sapces个空格
150152da9a59SGnoCiYeH                     tty.write(core, "        ".as_bytes(), spaces)?;
150252da9a59SGnoCiYeH                     return Ok(spaces);
150352da9a59SGnoCiYeH                 }
150452da9a59SGnoCiYeH                 self.cursor_column += spaces as u32;
150552da9a59SGnoCiYeH             }
150652da9a59SGnoCiYeH             _ => {
150752da9a59SGnoCiYeH                 // 判断是否为控制字符
150852da9a59SGnoCiYeH                 if !(c as char).is_control() {
150952da9a59SGnoCiYeH                     if termios.output_mode.contains(OutputMode::OLCUC) {
151052da9a59SGnoCiYeH                         c = c.to_ascii_uppercase();
151152da9a59SGnoCiYeH                     }
151252da9a59SGnoCiYeH 
151352da9a59SGnoCiYeH                     // 判断是否为utf8模式下的连续字符
151452da9a59SGnoCiYeH                     if !(termios.input_mode.contains(InputMode::IUTF8)
151552da9a59SGnoCiYeH                         && (c as usize) & 0xc0 == 0x80)
151652da9a59SGnoCiYeH                     {
151752da9a59SGnoCiYeH                         self.cursor_column += 1;
151852da9a59SGnoCiYeH                     }
151952da9a59SGnoCiYeH                 }
152052da9a59SGnoCiYeH             }
152152da9a59SGnoCiYeH         }
152252da9a59SGnoCiYeH 
152352da9a59SGnoCiYeH         if tty.put_char(tty.core(), c).is_err() {
152452da9a59SGnoCiYeH             tty.write(core, &[c], 1)?;
152552da9a59SGnoCiYeH         }
152652da9a59SGnoCiYeH         Ok(1)
152752da9a59SGnoCiYeH     }
1528dfe53cf0SGnoCiYeH 
packet_mode_flush(&self, tty: &TtyCoreData)1529dfe53cf0SGnoCiYeH     fn packet_mode_flush(&self, tty: &TtyCoreData) {
1530dfe53cf0SGnoCiYeH         let link = tty.link().unwrap();
1531dfe53cf0SGnoCiYeH         if link.core().contorl_info_irqsave().packet {
1532dfe53cf0SGnoCiYeH             tty.contorl_info_irqsave()
1533dfe53cf0SGnoCiYeH                 .pktstatus
1534dfe53cf0SGnoCiYeH                 .insert(TtyPacketStatus::TIOCPKT_FLUSHREAD);
1535dfe53cf0SGnoCiYeH 
1536dfe53cf0SGnoCiYeH             link.core().read_wq().wakeup_all();
1537dfe53cf0SGnoCiYeH         }
1538dfe53cf0SGnoCiYeH     }
153952da9a59SGnoCiYeH }
154052da9a59SGnoCiYeH 
154152da9a59SGnoCiYeH impl TtyLineDiscipline for NTtyLinediscipline {
open(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError>154252da9a59SGnoCiYeH     fn open(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
154352da9a59SGnoCiYeH         // 反向绑定tty到disc
15449365e801SGnoCiYeH         self.disc_data().tty = Arc::downgrade(&tty);
154552da9a59SGnoCiYeH         // 特定的tty设备在这里可能需要取消端口节流
154652da9a59SGnoCiYeH         return self.set_termios(tty, None);
154752da9a59SGnoCiYeH     }
154852da9a59SGnoCiYeH 
close(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError>154952da9a59SGnoCiYeH     fn close(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
155052da9a59SGnoCiYeH         todo!()
155152da9a59SGnoCiYeH     }
155252da9a59SGnoCiYeH 
155352da9a59SGnoCiYeH     /// ## 重置缓冲区的基本信息
flush_buffer(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError>155452da9a59SGnoCiYeH     fn flush_buffer(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
155552da9a59SGnoCiYeH         let core = tty.core();
155652da9a59SGnoCiYeH         let _ = core.termios();
155752da9a59SGnoCiYeH         let mut ldata = self.disc_data();
155852da9a59SGnoCiYeH         ldata.read_head = 0;
155952da9a59SGnoCiYeH         ldata.canon_head = 0;
156052da9a59SGnoCiYeH         ldata.read_tail = 0;
156152da9a59SGnoCiYeH         ldata.commit_head = 0;
156252da9a59SGnoCiYeH         ldata.line_start = 0;
156352da9a59SGnoCiYeH         ldata.erasing = false;
156452da9a59SGnoCiYeH         ldata.read_flags.set_all(false);
156552da9a59SGnoCiYeH         ldata.pushing = false;
156652da9a59SGnoCiYeH         ldata.lookahead_count = 0;
156752da9a59SGnoCiYeH 
156852da9a59SGnoCiYeH         // todo: kick worker?
1569dfe53cf0SGnoCiYeH         // packet mode?
1570dfe53cf0SGnoCiYeH         if core.link().is_some() {
1571dfe53cf0SGnoCiYeH             ldata.packet_mode_flush(core);
1572dfe53cf0SGnoCiYeH         }
157352da9a59SGnoCiYeH 
157452da9a59SGnoCiYeH         Ok(())
157552da9a59SGnoCiYeH     }
157652da9a59SGnoCiYeH 
157752bcb59eSGnoCiYeH     #[inline(never)]
read( &self, tty: Arc<TtyCore>, buf: &mut [u8], len: usize, cookie: &mut bool, _offset: usize, mode: FileMode, ) -> Result<usize, system_error::SystemError>157852da9a59SGnoCiYeH     fn read(
157952da9a59SGnoCiYeH         &self,
158052da9a59SGnoCiYeH         tty: Arc<TtyCore>,
158152da9a59SGnoCiYeH         buf: &mut [u8],
158252da9a59SGnoCiYeH         len: usize,
158352da9a59SGnoCiYeH         cookie: &mut bool,
158452da9a59SGnoCiYeH         _offset: usize,
158552da9a59SGnoCiYeH         mode: FileMode,
158652da9a59SGnoCiYeH     ) -> Result<usize, system_error::SystemError> {
158752da9a59SGnoCiYeH         let mut ldata;
158852da9a59SGnoCiYeH         if mode.contains(FileMode::O_NONBLOCK) {
158952da9a59SGnoCiYeH             let ret = self.disc_data_try_lock();
159052da9a59SGnoCiYeH             if ret.is_err() {
159152da9a59SGnoCiYeH                 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
159252da9a59SGnoCiYeH             }
159352da9a59SGnoCiYeH             ldata = ret.unwrap();
159452da9a59SGnoCiYeH         } else {
159552da9a59SGnoCiYeH             ldata = self.disc_data();
159652da9a59SGnoCiYeH         }
159752da9a59SGnoCiYeH         let core = tty.core();
159852da9a59SGnoCiYeH         let termios = core.termios();
159952da9a59SGnoCiYeH         let mut nr = len;
160052da9a59SGnoCiYeH 
160152da9a59SGnoCiYeH         let mut offset = 0;
160252da9a59SGnoCiYeH 
160352da9a59SGnoCiYeH         // 表示接着读
160452da9a59SGnoCiYeH         if *cookie {
160552da9a59SGnoCiYeH             // 规范且非拓展模式
160652da9a59SGnoCiYeH             if ldata.icanon && !termios.local_mode.contains(LocalMode::EXTPROC) {
160752da9a59SGnoCiYeH                 // 跳过EOF字符
160852da9a59SGnoCiYeH                 if len == 0 {
160952da9a59SGnoCiYeH                     ldata.canon_skip_eof();
161052da9a59SGnoCiYeH                 } else if ldata.canon_copy_from_read_buf(buf, &mut nr, &mut offset)? {
161152da9a59SGnoCiYeH                     return Ok(len - nr);
161252da9a59SGnoCiYeH                 }
1613b5b571e0SLoGin             } else if ldata.copy_from_read_buf(termios, buf, &mut nr, &mut offset)? {
161452da9a59SGnoCiYeH                 return Ok(len - nr);
161552da9a59SGnoCiYeH             }
161652da9a59SGnoCiYeH 
161752da9a59SGnoCiYeH             // 没有数据可读
161852da9a59SGnoCiYeH 
161952da9a59SGnoCiYeH             // todo: kick worker? or 关闭节流?
162052da9a59SGnoCiYeH 
162152da9a59SGnoCiYeH             *cookie = false;
162252da9a59SGnoCiYeH             return Ok(len - nr);
162352da9a59SGnoCiYeH         }
162452da9a59SGnoCiYeH 
162552da9a59SGnoCiYeH         drop(termios);
162652da9a59SGnoCiYeH 
162752da9a59SGnoCiYeH         TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTIN)?;
162852da9a59SGnoCiYeH 
162952da9a59SGnoCiYeH         let mut minimum: usize = 0;
163052da9a59SGnoCiYeH         if !ldata.icanon {
163152da9a59SGnoCiYeH             let core = tty.core();
163252da9a59SGnoCiYeH             let termios = core.termios();
163352da9a59SGnoCiYeH             minimum = termios.control_characters[ControlCharIndex::VMIN] as usize;
163452da9a59SGnoCiYeH             if minimum == 0 {
163552da9a59SGnoCiYeH                 minimum = 1;
163652da9a59SGnoCiYeH             }
163752da9a59SGnoCiYeH         }
163852da9a59SGnoCiYeH 
1639dfe53cf0SGnoCiYeH         let packet = core.contorl_info_irqsave().packet;
164052da9a59SGnoCiYeH         let mut ret: Result<usize, SystemError> = Ok(0);
164152da9a59SGnoCiYeH         // 记录读取前 的tail
164252da9a59SGnoCiYeH         let tail = ldata.read_tail;
164352da9a59SGnoCiYeH         drop(ldata);
164452da9a59SGnoCiYeH         while nr != 0 {
164552da9a59SGnoCiYeH             // todo: 处理packet模式
1646dfe53cf0SGnoCiYeH             if packet {
1647dfe53cf0SGnoCiYeH                 let link = core.link().unwrap();
1648dfe53cf0SGnoCiYeH                 let link = link.core();
1649dfe53cf0SGnoCiYeH                 let mut ctrl = link.contorl_info_irqsave();
1650dfe53cf0SGnoCiYeH                 if !ctrl.pktstatus.is_empty() {
1651dfe53cf0SGnoCiYeH                     if offset != 0 {
1652dfe53cf0SGnoCiYeH                         break;
1653dfe53cf0SGnoCiYeH                     }
1654dfe53cf0SGnoCiYeH                     let cs = ctrl.pktstatus;
1655dfe53cf0SGnoCiYeH                     ctrl.pktstatus = TtyPacketStatus::empty();
1656dfe53cf0SGnoCiYeH 
1657dfe53cf0SGnoCiYeH                     buf[offset] = cs.bits();
1658dfe53cf0SGnoCiYeH                     offset += 1;
1659dfe53cf0SGnoCiYeH                     // nr -= 1;
1660dfe53cf0SGnoCiYeH                     break;
1661dfe53cf0SGnoCiYeH                 }
1662dfe53cf0SGnoCiYeH             }
1663dfe53cf0SGnoCiYeH 
166452da9a59SGnoCiYeH             let mut ldata = self.disc_data();
166552da9a59SGnoCiYeH 
166652da9a59SGnoCiYeH             let core = tty.core();
166752da9a59SGnoCiYeH             if !ldata.input_available(core.termios(), false) {
166852da9a59SGnoCiYeH                 if core.flags().contains(TtyFlag::OTHER_CLOSED) {
166952da9a59SGnoCiYeH                     ret = Err(SystemError::EIO);
167052da9a59SGnoCiYeH                     break;
167152da9a59SGnoCiYeH                 }
167252da9a59SGnoCiYeH 
167352da9a59SGnoCiYeH                 if core.flags().contains(TtyFlag::HUPPED) || core.flags().contains(TtyFlag::HUPPING)
167452da9a59SGnoCiYeH                 {
167552da9a59SGnoCiYeH                     break;
167652da9a59SGnoCiYeH                 }
167752da9a59SGnoCiYeH 
167852da9a59SGnoCiYeH                 if mode.contains(FileMode::O_NONBLOCK)
167952da9a59SGnoCiYeH                     || core.flags().contains(TtyFlag::LDISC_CHANGING)
168052da9a59SGnoCiYeH                 {
168152da9a59SGnoCiYeH                     ret = Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
168252da9a59SGnoCiYeH                     break;
168352da9a59SGnoCiYeH                 }
168452da9a59SGnoCiYeH 
168552da9a59SGnoCiYeH                 if ProcessManager::current_pcb()
168652bcb59eSGnoCiYeH                     .sig_info_irqsave()
168752da9a59SGnoCiYeH                     .sig_pending()
168852da9a59SGnoCiYeH                     .has_pending()
168952da9a59SGnoCiYeH                 {
169052da9a59SGnoCiYeH                     ret = Err(SystemError::ERESTARTSYS);
169152da9a59SGnoCiYeH                     break;
169252da9a59SGnoCiYeH                 }
169352da9a59SGnoCiYeH 
169452da9a59SGnoCiYeH                 // 休眠一段时间
169552da9a59SGnoCiYeH                 // 获取到termios读锁,避免termios被更改导致行为异常
169652da9a59SGnoCiYeH                 // let termios = core.termios_preempt_enable();
169752da9a59SGnoCiYeH                 // let helper = WakeUpHelper::new(ProcessManager::current_pcb());
169852da9a59SGnoCiYeH                 // let wakeup_helper = Timer::new(helper, timeout);
169952da9a59SGnoCiYeH                 // wakeup_helper.activate();
170052da9a59SGnoCiYeH                 // drop(termios);
170152da9a59SGnoCiYeH                 drop(ldata);
170252da9a59SGnoCiYeH                 core.read_wq()
170352da9a59SGnoCiYeH                     .sleep((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64);
170452da9a59SGnoCiYeH                 continue;
170552da9a59SGnoCiYeH             }
170652da9a59SGnoCiYeH 
170752da9a59SGnoCiYeH             if ldata.icanon && !core.termios().local_mode.contains(LocalMode::EXTPROC) {
170852da9a59SGnoCiYeH                 if ldata.canon_copy_from_read_buf(buf, &mut nr, &mut offset)? {
170952da9a59SGnoCiYeH                     *cookie = true;
171052da9a59SGnoCiYeH                     offset += len - nr;
171152da9a59SGnoCiYeH                     return Ok(offset);
171252da9a59SGnoCiYeH                 }
171352da9a59SGnoCiYeH             } else {
171452da9a59SGnoCiYeH                 // 非标准模式
171552da9a59SGnoCiYeH                 // todo: 处理packet模式
1716dfe53cf0SGnoCiYeH                 if packet && offset == 0 {
1717dfe53cf0SGnoCiYeH                     buf[offset] = TtyPacketStatus::TIOCPKT_DATA.bits();
1718dfe53cf0SGnoCiYeH                     offset += 1;
1719dfe53cf0SGnoCiYeH                     nr -= 1;
1720dfe53cf0SGnoCiYeH                 }
172152da9a59SGnoCiYeH                 // 拷贝数据
172252da9a59SGnoCiYeH                 if ldata.copy_from_read_buf(core.termios(), buf, &mut nr, &mut offset)?
172352da9a59SGnoCiYeH                     && offset >= minimum
172452da9a59SGnoCiYeH                 {
172552da9a59SGnoCiYeH                     *cookie = true;
172652da9a59SGnoCiYeH                     return Ok(offset);
172752da9a59SGnoCiYeH                 }
172852da9a59SGnoCiYeH             }
172952da9a59SGnoCiYeH 
173052da9a59SGnoCiYeH             if offset >= minimum {
173152da9a59SGnoCiYeH                 break;
173252da9a59SGnoCiYeH             }
173352da9a59SGnoCiYeH         }
173452da9a59SGnoCiYeH         let ldata = self.disc_data();
173552da9a59SGnoCiYeH         if tail != ldata.read_tail {
173652da9a59SGnoCiYeH             // todo: kick worker?
173752da9a59SGnoCiYeH         }
173852da9a59SGnoCiYeH 
173952da9a59SGnoCiYeH         if offset > 0 {
174052da9a59SGnoCiYeH             return Ok(offset);
174152da9a59SGnoCiYeH         }
174252da9a59SGnoCiYeH 
174352da9a59SGnoCiYeH         ret
174452da9a59SGnoCiYeH     }
174552da9a59SGnoCiYeH 
174652bcb59eSGnoCiYeH     #[inline(never)]
write( &self, tty: Arc<TtyCore>, buf: &[u8], len: usize, mode: FileMode, ) -> Result<usize, system_error::SystemError>174752da9a59SGnoCiYeH     fn write(
174852da9a59SGnoCiYeH         &self,
174952da9a59SGnoCiYeH         tty: Arc<TtyCore>,
175052da9a59SGnoCiYeH         buf: &[u8],
175152da9a59SGnoCiYeH         len: usize,
175252da9a59SGnoCiYeH         mode: FileMode,
175352da9a59SGnoCiYeH     ) -> Result<usize, system_error::SystemError> {
175452da9a59SGnoCiYeH         let mut nr = len;
175552da9a59SGnoCiYeH         let mut ldata = self.disc_data();
175652da9a59SGnoCiYeH         let pcb = ProcessManager::current_pcb();
175752da9a59SGnoCiYeH         let binding = tty.clone();
175852da9a59SGnoCiYeH         let core = binding.core();
1759b5b571e0SLoGin         let termios = *core.termios();
176052da9a59SGnoCiYeH         if termios.local_mode.contains(LocalMode::TOSTOP) {
176152da9a59SGnoCiYeH             TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTOU)?;
176252da9a59SGnoCiYeH         }
176352da9a59SGnoCiYeH 
176452da9a59SGnoCiYeH         ldata.process_echoes(tty.clone());
176552da9a59SGnoCiYeH         // drop(ldata);
176652da9a59SGnoCiYeH         let mut offset = 0;
176752da9a59SGnoCiYeH         loop {
176852bcb59eSGnoCiYeH             if pcb.sig_info_irqsave().sig_pending().has_pending() {
176952da9a59SGnoCiYeH                 return Err(SystemError::ERESTARTSYS);
177052da9a59SGnoCiYeH             }
177152da9a59SGnoCiYeH             if core.flags().contains(TtyFlag::HUPPED) {
177252da9a59SGnoCiYeH                 return Err(SystemError::EIO);
177352da9a59SGnoCiYeH             }
177452da9a59SGnoCiYeH             if termios.output_mode.contains(OutputMode::OPOST) {
177552da9a59SGnoCiYeH                 while nr > 0 {
177652da9a59SGnoCiYeH                     // let mut ldata = self.disc_data();
177752da9a59SGnoCiYeH                     // 获得一次处理后的数量
177852da9a59SGnoCiYeH                     let ret = ldata.process_output_block(core, core.termios(), &buf[offset..], nr);
177952da9a59SGnoCiYeH                     let num = match ret {
178052da9a59SGnoCiYeH                         Ok(num) => num,
178152da9a59SGnoCiYeH                         Err(e) => {
178252da9a59SGnoCiYeH                             if e == SystemError::EAGAIN_OR_EWOULDBLOCK {
178352da9a59SGnoCiYeH                                 break;
178452da9a59SGnoCiYeH                             } else {
178552da9a59SGnoCiYeH                                 return Err(e);
178652da9a59SGnoCiYeH                             }
178752da9a59SGnoCiYeH                         }
178852da9a59SGnoCiYeH                     };
178952da9a59SGnoCiYeH 
179052da9a59SGnoCiYeH                     offset += num;
179152da9a59SGnoCiYeH                     nr -= num;
179252da9a59SGnoCiYeH 
179352da9a59SGnoCiYeH                     if nr == 0 {
179452da9a59SGnoCiYeH                         break;
179552da9a59SGnoCiYeH                     }
179652da9a59SGnoCiYeH 
179752da9a59SGnoCiYeH                     let c = buf[offset];
179852da9a59SGnoCiYeH                     if !ldata.process_output(tty.clone(), c) {
179952da9a59SGnoCiYeH                         break;
180052da9a59SGnoCiYeH                     }
180152da9a59SGnoCiYeH                     offset += 1;
180252da9a59SGnoCiYeH                     nr -= 1;
180352da9a59SGnoCiYeH                 }
180452da9a59SGnoCiYeH 
1805b5b571e0SLoGin                 tty.flush_chars(core);
180652da9a59SGnoCiYeH             } else {
180752da9a59SGnoCiYeH                 while nr > 0 {
180852da9a59SGnoCiYeH                     let write = tty.write(core, &buf[offset..], nr)?;
180952da9a59SGnoCiYeH                     if write == 0 {
181052da9a59SGnoCiYeH                         break;
181152da9a59SGnoCiYeH                     }
181252da9a59SGnoCiYeH                     offset += write;
181352da9a59SGnoCiYeH                     nr -= write;
181452da9a59SGnoCiYeH                 }
181552da9a59SGnoCiYeH             }
181652da9a59SGnoCiYeH 
181752da9a59SGnoCiYeH             if nr == 0 {
181852da9a59SGnoCiYeH                 break;
181952da9a59SGnoCiYeH             }
182052da9a59SGnoCiYeH 
182152da9a59SGnoCiYeH             if mode.contains(FileMode::O_NONBLOCK) || core.flags().contains(TtyFlag::LDISC_CHANGING)
182252da9a59SGnoCiYeH             {
182352da9a59SGnoCiYeH                 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
182452da9a59SGnoCiYeH             }
182552da9a59SGnoCiYeH 
182652da9a59SGnoCiYeH             // 到这里表明没位置可写了
182752da9a59SGnoCiYeH             // 休眠一段时间
182852da9a59SGnoCiYeH             // 获取到termios读锁,避免termios被更改导致行为异常
182952da9a59SGnoCiYeH             core.write_wq()
183052da9a59SGnoCiYeH                 .sleep(EPollEventType::EPOLLOUT.bits() as u64);
183152da9a59SGnoCiYeH         }
183252da9a59SGnoCiYeH 
183352da9a59SGnoCiYeH         Ok(offset)
183452da9a59SGnoCiYeH     }
183552da9a59SGnoCiYeH 
ioctl( &self, tty: Arc<TtyCore>, cmd: u32, arg: usize, ) -> Result<usize, system_error::SystemError>183652da9a59SGnoCiYeH     fn ioctl(
183752da9a59SGnoCiYeH         &self,
183852da9a59SGnoCiYeH         tty: Arc<TtyCore>,
183952da9a59SGnoCiYeH         cmd: u32,
184052da9a59SGnoCiYeH         arg: usize,
184152da9a59SGnoCiYeH     ) -> Result<usize, system_error::SystemError> {
184252da9a59SGnoCiYeH         match cmd {
184352da9a59SGnoCiYeH             TtyIoctlCmd::TIOCOUTQ => {
184452da9a59SGnoCiYeH                 let mut user_writer = UserBufferWriter::new(
184552da9a59SGnoCiYeH                     VirtAddr::new(arg).as_ptr::<i32>(),
184652da9a59SGnoCiYeH                     core::mem::size_of::<i32>(),
184752da9a59SGnoCiYeH                     true,
184852da9a59SGnoCiYeH                 )?;
184952da9a59SGnoCiYeH 
185052da9a59SGnoCiYeH                 let count = tty.chars_in_buffer();
185152da9a59SGnoCiYeH                 user_writer.copy_one_to_user::<i32>(&(count as i32), 0)?;
185252da9a59SGnoCiYeH                 return Ok(0);
185352da9a59SGnoCiYeH             }
185452da9a59SGnoCiYeH             TtyIoctlCmd::FIONREAD => {
185552da9a59SGnoCiYeH                 let ldata = self.disc_data();
185652da9a59SGnoCiYeH                 let termios = tty.core().termios();
185752da9a59SGnoCiYeH                 let retval;
185852da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::ICANON)
185952da9a59SGnoCiYeH                     && !termios.local_mode.contains(LocalMode::EXTPROC)
186052da9a59SGnoCiYeH                 {
186152da9a59SGnoCiYeH                     if ldata.canon_head == ldata.read_tail {
186252da9a59SGnoCiYeH                         retval = 0;
186352da9a59SGnoCiYeH                     } else {
186452da9a59SGnoCiYeH                         let head = ldata.canon_head;
186552da9a59SGnoCiYeH                         let mut tail = ldata.read_tail;
186652da9a59SGnoCiYeH                         let mut nr = head - tail;
186752da9a59SGnoCiYeH 
186852da9a59SGnoCiYeH                         while ntty_buf_mask(head) != ntty_buf_mask(tail) {
186952da9a59SGnoCiYeH                             if ldata.read_flags.get(ntty_buf_mask(tail)).unwrap()
187052da9a59SGnoCiYeH                                 && ldata.read_buf[ntty_buf_mask(tail)]
187152da9a59SGnoCiYeH                                     == ControlCharIndex::DISABLE_CHAR
187252da9a59SGnoCiYeH                             {
187352da9a59SGnoCiYeH                                 nr -= 1;
187452da9a59SGnoCiYeH                             }
187552da9a59SGnoCiYeH                             tail += 1;
187652da9a59SGnoCiYeH                         }
187752da9a59SGnoCiYeH 
187852da9a59SGnoCiYeH                         retval = nr;
187952da9a59SGnoCiYeH                     }
188052da9a59SGnoCiYeH                 } else {
188152da9a59SGnoCiYeH                     retval = ldata.read_cnt();
188252da9a59SGnoCiYeH                 }
188352da9a59SGnoCiYeH 
188452da9a59SGnoCiYeH                 let mut user_writer = UserBufferWriter::new(
188552da9a59SGnoCiYeH                     VirtAddr::new(arg).as_ptr::<i32>(),
188652da9a59SGnoCiYeH                     core::mem::size_of::<i32>(),
188752da9a59SGnoCiYeH                     true,
188852da9a59SGnoCiYeH                 )?;
188952da9a59SGnoCiYeH 
189052da9a59SGnoCiYeH                 user_writer.copy_one_to_user::<i32>(&(retval as i32), 0)?;
189152da9a59SGnoCiYeH                 return Ok(0);
189252da9a59SGnoCiYeH             }
189352da9a59SGnoCiYeH             _ => {
189452da9a59SGnoCiYeH                 return self.ioctl_helper(tty, cmd, arg);
189552da9a59SGnoCiYeH             }
189652da9a59SGnoCiYeH         }
189752da9a59SGnoCiYeH     }
189852da9a59SGnoCiYeH 
189952bcb59eSGnoCiYeH     #[inline(never)]
set_termios( &self, tty: Arc<TtyCore>, old: Option<crate::driver::tty::termios::Termios>, ) -> Result<(), system_error::SystemError>190052da9a59SGnoCiYeH     fn set_termios(
190152da9a59SGnoCiYeH         &self,
190252da9a59SGnoCiYeH         tty: Arc<TtyCore>,
190352da9a59SGnoCiYeH         old: Option<crate::driver::tty::termios::Termios>,
190452da9a59SGnoCiYeH     ) -> Result<(), system_error::SystemError> {
190552da9a59SGnoCiYeH         let core = tty.core();
190652da9a59SGnoCiYeH         let termios = core.termios();
190752da9a59SGnoCiYeH         let mut ldata = self.disc_data();
190852da9a59SGnoCiYeH         let contorl_chars = termios.control_characters;
190952da9a59SGnoCiYeH 
191052da9a59SGnoCiYeH         // 第一次设置或者规范模式 (ICANON) 或者扩展处理 (EXTPROC) 标志发生变化
191152bcb59eSGnoCiYeH         let mut spec_mode_changed = false;
1912b5b571e0SLoGin         if let Some(old) = old {
1913b5b571e0SLoGin             let local_mode = old.local_mode.bitxor(termios.local_mode);
191452bcb59eSGnoCiYeH             spec_mode_changed =
191552bcb59eSGnoCiYeH                 local_mode.contains(LocalMode::ICANON) || local_mode.contains(LocalMode::EXTPROC);
191652bcb59eSGnoCiYeH         }
191752bcb59eSGnoCiYeH         if old.is_none() || spec_mode_changed {
191852da9a59SGnoCiYeH             // 重置read_flags
191952da9a59SGnoCiYeH             ldata.read_flags.set_all(false);
192052da9a59SGnoCiYeH 
192152da9a59SGnoCiYeH             ldata.line_start = ldata.read_tail;
192252da9a59SGnoCiYeH 
192352da9a59SGnoCiYeH             // 不是规范模式或者有可读数据
192452da9a59SGnoCiYeH             if !termios.local_mode.contains(LocalMode::ICANON) || ldata.read_cnt() != 0 {
192552da9a59SGnoCiYeH                 ldata.canon_head = ldata.read_tail;
192652da9a59SGnoCiYeH                 ldata.pushing = false;
192752da9a59SGnoCiYeH             } else {
192852da9a59SGnoCiYeH                 let read_head = ldata.read_head;
192952da9a59SGnoCiYeH                 ldata
193052da9a59SGnoCiYeH                     .read_flags
193152da9a59SGnoCiYeH                     .set((read_head - 1) & (NTTY_BUFSIZE - 1), true);
193252da9a59SGnoCiYeH                 ldata.canon_head = ldata.read_head;
193352da9a59SGnoCiYeH                 ldata.pushing = true;
193452da9a59SGnoCiYeH             }
193552da9a59SGnoCiYeH             ldata.commit_head = ldata.read_head;
193652da9a59SGnoCiYeH             ldata.erasing = false;
193752da9a59SGnoCiYeH             ldata.lnext = false;
193852da9a59SGnoCiYeH         }
193952da9a59SGnoCiYeH 
194052bcb59eSGnoCiYeH         // 设置模式
194152bcb59eSGnoCiYeH         ldata.icanon = termios.local_mode.contains(LocalMode::ICANON);
194252da9a59SGnoCiYeH 
194352da9a59SGnoCiYeH         // 设置回显
194452da9a59SGnoCiYeH         if termios.local_mode.contains(LocalMode::ECHO) {
194552da9a59SGnoCiYeH             ldata.echo = true;
194652da9a59SGnoCiYeH         }
194752da9a59SGnoCiYeH 
194852da9a59SGnoCiYeH         if termios.input_mode.contains(InputMode::ISTRIP)
194952da9a59SGnoCiYeH             || termios.input_mode.contains(InputMode::IUCLC)
195052da9a59SGnoCiYeH             || termios.input_mode.contains(InputMode::IGNCR)
195152da9a59SGnoCiYeH             || termios.input_mode.contains(InputMode::IXON)
195252da9a59SGnoCiYeH             || termios.local_mode.contains(LocalMode::ISIG)
195352da9a59SGnoCiYeH             || termios.local_mode.contains(LocalMode::ECHO)
195452da9a59SGnoCiYeH             || termios.input_mode.contains(InputMode::PARMRK)
195552da9a59SGnoCiYeH         {
195652da9a59SGnoCiYeH             // 非原模式
195752da9a59SGnoCiYeH 
195852da9a59SGnoCiYeH             ldata.char_map.set_all(false);
195952da9a59SGnoCiYeH 
196052da9a59SGnoCiYeH             // 忽略回车符或者将回车映射为换行符
196152da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::IGNCR)
196252da9a59SGnoCiYeH                 || termios.input_mode.contains(InputMode::ICRNL)
196352da9a59SGnoCiYeH             {
196452da9a59SGnoCiYeH                 ldata.char_map.set('\r' as usize, true);
196552da9a59SGnoCiYeH             }
196652da9a59SGnoCiYeH 
196752da9a59SGnoCiYeH             // 将换行映射为回车
196852da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::INLCR) {
196952da9a59SGnoCiYeH                 ldata.char_map.set('\n' as usize, true);
197052da9a59SGnoCiYeH             }
197152da9a59SGnoCiYeH 
197252da9a59SGnoCiYeH             // 规范模式
197352da9a59SGnoCiYeH             if termios.local_mode.contains(LocalMode::ICANON) {
197452da9a59SGnoCiYeH                 ldata
197552da9a59SGnoCiYeH                     .char_map
197652da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VERASE] as usize, true);
197752da9a59SGnoCiYeH                 ldata
197852da9a59SGnoCiYeH                     .char_map
197952da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VKILL] as usize, true);
198052da9a59SGnoCiYeH                 ldata
198152da9a59SGnoCiYeH                     .char_map
198252da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VEOF] as usize, true);
198352da9a59SGnoCiYeH                 ldata.char_map.set('\n' as usize, true);
198452da9a59SGnoCiYeH                 ldata
198552da9a59SGnoCiYeH                     .char_map
198652da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VEOL] as usize, true);
198752da9a59SGnoCiYeH 
198852da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::IEXTEN) {
198952da9a59SGnoCiYeH                     ldata
199052da9a59SGnoCiYeH                         .char_map
199152da9a59SGnoCiYeH                         .set(contorl_chars[ControlCharIndex::VWERASE] as usize, true);
199252da9a59SGnoCiYeH                     ldata
199352da9a59SGnoCiYeH                         .char_map
199452da9a59SGnoCiYeH                         .set(contorl_chars[ControlCharIndex::VLNEXT] as usize, true);
199552da9a59SGnoCiYeH                     ldata
199652da9a59SGnoCiYeH                         .char_map
199752da9a59SGnoCiYeH                         .set(contorl_chars[ControlCharIndex::VEOL2] as usize, true);
199852da9a59SGnoCiYeH                     if termios.local_mode.contains(LocalMode::ECHO) {
199952da9a59SGnoCiYeH                         ldata
200052da9a59SGnoCiYeH                             .char_map
200152da9a59SGnoCiYeH                             .set(contorl_chars[ControlCharIndex::VREPRINT] as usize, true);
200252da9a59SGnoCiYeH                     }
200352da9a59SGnoCiYeH                 }
200452da9a59SGnoCiYeH             }
200552da9a59SGnoCiYeH 
200652da9a59SGnoCiYeH             // 软件流控制
200752da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::IXON) {
200852da9a59SGnoCiYeH                 ldata
200952da9a59SGnoCiYeH                     .char_map
201052da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VSTART] as usize, true);
201152da9a59SGnoCiYeH                 ldata
201252da9a59SGnoCiYeH                     .char_map
201352da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VSTOP] as usize, true);
201452da9a59SGnoCiYeH             }
201552da9a59SGnoCiYeH 
201652da9a59SGnoCiYeH             if termios.local_mode.contains(LocalMode::ISIG) {
201752da9a59SGnoCiYeH                 ldata
201852da9a59SGnoCiYeH                     .char_map
201952da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VINTR] as usize, true);
202052da9a59SGnoCiYeH                 ldata
202152da9a59SGnoCiYeH                     .char_map
202252da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VQUIT] as usize, true);
202352da9a59SGnoCiYeH                 ldata
202452da9a59SGnoCiYeH                     .char_map
202552da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VSUSP] as usize, true);
202652da9a59SGnoCiYeH             }
202752da9a59SGnoCiYeH 
202852da9a59SGnoCiYeH             ldata
202952da9a59SGnoCiYeH                 .char_map
203052da9a59SGnoCiYeH                 .set(ControlCharIndex::DISABLE_CHAR as usize, true);
203152da9a59SGnoCiYeH             ldata.raw = false;
203252da9a59SGnoCiYeH             ldata.real_raw = false;
203352da9a59SGnoCiYeH         } else {
203452da9a59SGnoCiYeH             // 原模式或real_raw
203552da9a59SGnoCiYeH             ldata.raw = true;
203652da9a59SGnoCiYeH 
2037b5b571e0SLoGin             ldata.real_raw = termios.input_mode.contains(InputMode::IGNBRK)
203852da9a59SGnoCiYeH                 || (!termios.input_mode.contains(InputMode::BRKINT)
203952da9a59SGnoCiYeH                     && !termios.input_mode.contains(InputMode::PARMRK))
204052da9a59SGnoCiYeH                     && (termios.input_mode.contains(InputMode::IGNPAR)
204152da9a59SGnoCiYeH                         || !termios.input_mode.contains(InputMode::INPCK))
204252da9a59SGnoCiYeH                     && (core
204352da9a59SGnoCiYeH                         .driver()
204452da9a59SGnoCiYeH                         .flags()
2045b5b571e0SLoGin                         .contains(TtyDriverFlag::TTY_DRIVER_REAL_RAW));
204652da9a59SGnoCiYeH         }
204752da9a59SGnoCiYeH 
204852da9a59SGnoCiYeH         // if !termios.input_mode.contains(InputMode::IXON)
204952da9a59SGnoCiYeH         //     && old.is_some()
205052da9a59SGnoCiYeH         //     && old.unwrap().input_mode.contains(InputMode::IXON) && !
205152da9a59SGnoCiYeH         // {}
205252da9a59SGnoCiYeH 
205352da9a59SGnoCiYeH         core.read_wq().wakeup_all();
205452da9a59SGnoCiYeH         core.write_wq().wakeup_all();
205552da9a59SGnoCiYeH         Ok(())
205652da9a59SGnoCiYeH     }
205752da9a59SGnoCiYeH 
poll(&self, tty: Arc<TtyCore>) -> Result<usize, system_error::SystemError>205852bcb59eSGnoCiYeH     fn poll(&self, tty: Arc<TtyCore>) -> Result<usize, system_error::SystemError> {
205952bcb59eSGnoCiYeH         let core = tty.core();
206052bcb59eSGnoCiYeH         let ldata = self.disc_data();
206152bcb59eSGnoCiYeH 
206252bcb59eSGnoCiYeH         let mut event = EPollEventType::empty();
206352bcb59eSGnoCiYeH         if ldata.input_available(core.termios(), true) {
206452bcb59eSGnoCiYeH             event.insert(EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM)
206552bcb59eSGnoCiYeH         }
206652bcb59eSGnoCiYeH 
206752bcb59eSGnoCiYeH         if core.contorl_info_irqsave().packet {
206852bcb59eSGnoCiYeH             let link = core.link();
2069dfe53cf0SGnoCiYeH             if link.is_some()
2070dfe53cf0SGnoCiYeH                 && !link
2071dfe53cf0SGnoCiYeH                     .unwrap()
2072dfe53cf0SGnoCiYeH                     .core()
2073dfe53cf0SGnoCiYeH                     .contorl_info_irqsave()
2074dfe53cf0SGnoCiYeH                     .pktstatus
2075dfe53cf0SGnoCiYeH                     .is_empty()
2076dfe53cf0SGnoCiYeH             {
207752bcb59eSGnoCiYeH                 event.insert(
207852bcb59eSGnoCiYeH                     EPollEventType::EPOLLPRI
207952bcb59eSGnoCiYeH                         | EPollEventType::EPOLLIN
208052bcb59eSGnoCiYeH                         | EPollEventType::EPOLLRDNORM,
208152bcb59eSGnoCiYeH                 );
208252bcb59eSGnoCiYeH             }
208352bcb59eSGnoCiYeH         }
208452bcb59eSGnoCiYeH 
208552bcb59eSGnoCiYeH         if core.flags().contains(TtyFlag::OTHER_CLOSED) {
208652bcb59eSGnoCiYeH             event.insert(EPollEventType::EPOLLHUP);
208752bcb59eSGnoCiYeH         }
208852bcb59eSGnoCiYeH 
208952bcb59eSGnoCiYeH         if core.driver().driver_funcs().chars_in_buffer() < 256
209052bcb59eSGnoCiYeH             && core.driver().driver_funcs().write_room(core) > 0
209152bcb59eSGnoCiYeH         {
209252bcb59eSGnoCiYeH             event.insert(EPollEventType::EPOLLOUT | EPollEventType::EPOLLWRNORM);
209352bcb59eSGnoCiYeH         }
209452bcb59eSGnoCiYeH 
209552bcb59eSGnoCiYeH         Ok(event.bits() as usize)
209652da9a59SGnoCiYeH     }
209752da9a59SGnoCiYeH 
hangup(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError>209852da9a59SGnoCiYeH     fn hangup(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
209952da9a59SGnoCiYeH         todo!()
210052da9a59SGnoCiYeH     }
210152da9a59SGnoCiYeH 
receive_buf( &self, tty: Arc<TtyCore>, buf: &[u8], flags: Option<&[u8]>, count: usize, ) -> Result<usize, SystemError>210252da9a59SGnoCiYeH     fn receive_buf(
210352da9a59SGnoCiYeH         &self,
210452da9a59SGnoCiYeH         tty: Arc<TtyCore>,
210552da9a59SGnoCiYeH         buf: &[u8],
210652da9a59SGnoCiYeH         flags: Option<&[u8]>,
210752da9a59SGnoCiYeH         count: usize,
210852da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
210952da9a59SGnoCiYeH         let mut ldata = self.disc_data();
211052da9a59SGnoCiYeH         ldata.receive_buf_common(tty, buf, flags, count, false)
211152da9a59SGnoCiYeH     }
211252da9a59SGnoCiYeH 
receive_buf2( &self, tty: Arc<TtyCore>, buf: &[u8], flags: Option<&[u8]>, count: usize, ) -> Result<usize, SystemError>211352da9a59SGnoCiYeH     fn receive_buf2(
211452da9a59SGnoCiYeH         &self,
211552da9a59SGnoCiYeH         tty: Arc<TtyCore>,
211652da9a59SGnoCiYeH         buf: &[u8],
211752da9a59SGnoCiYeH         flags: Option<&[u8]>,
211852da9a59SGnoCiYeH         count: usize,
211952da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
212052da9a59SGnoCiYeH         let mut ldata = self.disc_data();
212152da9a59SGnoCiYeH         ldata.receive_buf_common(tty, buf, flags, count, true)
212252da9a59SGnoCiYeH     }
212352da9a59SGnoCiYeH }
2124