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