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}, 1352da9a59SGnoCiYeH tty_core::{EchoOperation, TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd}, 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 3452da9a59SGnoCiYeH 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] 4552da9a59SGnoCiYeH pub fn disc_data(&self) -> SpinLockGuard<NTtyData> { 4652da9a59SGnoCiYeH self.data.lock_irqsave() 4752da9a59SGnoCiYeH } 4852da9a59SGnoCiYeH 4952da9a59SGnoCiYeH #[inline] 5052da9a59SGnoCiYeH pub fn disc_data_try_lock(&self) -> Result<SpinLockGuard<NTtyData>, SystemError> { 5152da9a59SGnoCiYeH self.data.try_lock_irqsave() 5252da9a59SGnoCiYeH } 5352da9a59SGnoCiYeH 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 12552da9a59SGnoCiYeH tty: Option<Weak<TtyCore>>, 12652da9a59SGnoCiYeH } 12752da9a59SGnoCiYeH 12852da9a59SGnoCiYeH impl NTtyData { 12952da9a59SGnoCiYeH 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(), 15452da9a59SGnoCiYeH tty: None, 15552da9a59SGnoCiYeH no_room: false, 15652da9a59SGnoCiYeH } 15752da9a59SGnoCiYeH } 15852da9a59SGnoCiYeH 15952da9a59SGnoCiYeH #[inline] 16052da9a59SGnoCiYeH pub fn read_cnt(&self) -> usize { 16152da9a59SGnoCiYeH self.read_head - self.read_tail 16252da9a59SGnoCiYeH } 16352da9a59SGnoCiYeH 16452da9a59SGnoCiYeH #[inline] 16552da9a59SGnoCiYeH pub fn read_at(&self, i: usize) -> u8 { 16652da9a59SGnoCiYeH let i = i & (NTTY_BUFSIZE - 1); 16752da9a59SGnoCiYeH self.read_buf[i] 16852da9a59SGnoCiYeH } 16952da9a59SGnoCiYeH 17052da9a59SGnoCiYeH /// ### 接收数据到NTTY 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 { 212*b5b571e0SLoGin if let Some(flags) = flags { 213*b5b571e0SLoGin self.receive_buf(tty.clone(), &buf[offset..], Some(&flags[offset..]), n); 21452da9a59SGnoCiYeH } else { 215*b5b571e0SLoGin 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 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 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 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 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 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 39152da9a59SGnoCiYeH if self.char_map.get(c as usize).unwrap() { 39252da9a59SGnoCiYeH // 特殊字符 39352da9a59SGnoCiYeH 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)] 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)] 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 70952da9a59SGnoCiYeH fn finish_erasing(&mut self) { 71052da9a59SGnoCiYeH if self.erasing { 71152da9a59SGnoCiYeH self.echo_char_raw(b'/'); 71252da9a59SGnoCiYeH self.erasing = false; 71352da9a59SGnoCiYeH } 71452da9a59SGnoCiYeH } 71552da9a59SGnoCiYeH 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 /// 检测是否为多字节字符的后续字节 73152da9a59SGnoCiYeH fn is_continuation(c: u8, termios: &RwLockReadGuard<Termios>) -> bool { 73252da9a59SGnoCiYeH return termios.input_mode.contains(InputMode::IUTF8) && (c & 0xc0) == 0x80; 73352da9a59SGnoCiYeH } 73452da9a59SGnoCiYeH 73552da9a59SGnoCiYeH /// ## 该字符是否已经当做流控字符处理 73652da9a59SGnoCiYeH 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 /// ## 接收到信号字符时的处理 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 /// ## 处理输入信号 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; 790*b5b571e0SLoGin if let Some(pg) = pg { 791*b5b571e0SLoGin 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; 81552da9a59SGnoCiYeH } 81652da9a59SGnoCiYeH } 81752da9a59SGnoCiYeH 81852da9a59SGnoCiYeH pub fn receive_char(&mut self, c: u8, tty: Arc<TtyCore>) { 81952da9a59SGnoCiYeH let termios = tty.core().termios(); 82052da9a59SGnoCiYeH 82152da9a59SGnoCiYeH if termios.local_mode.contains(LocalMode::ECHO) { 82252da9a59SGnoCiYeH if self.erasing { 82352da9a59SGnoCiYeH self.add_echo_byte(b'/'); 82452da9a59SGnoCiYeH self.erasing = false; 82552da9a59SGnoCiYeH } 82652da9a59SGnoCiYeH 82752da9a59SGnoCiYeH if self.canon_head == self.read_head { 82852da9a59SGnoCiYeH self.add_echo_byte(EchoOperation::Start.to_u8()); 82952da9a59SGnoCiYeH self.add_echo_byte(EchoOperation::SetCanonCol.to_u8()); 83052da9a59SGnoCiYeH } 83152da9a59SGnoCiYeH 83252da9a59SGnoCiYeH self.echo_char(c, &termios); 83352da9a59SGnoCiYeH self.commit_echoes(tty.clone()); 83452da9a59SGnoCiYeH } 83552da9a59SGnoCiYeH 83652da9a59SGnoCiYeH if c == 0o377 && tty.core().termios().input_mode.contains(InputMode::PARMRK) { 83752da9a59SGnoCiYeH self.add_read_byte(c); 83852da9a59SGnoCiYeH } 83952da9a59SGnoCiYeH self.add_read_byte(c); 84052da9a59SGnoCiYeH } 84152da9a59SGnoCiYeH 84252da9a59SGnoCiYeH pub fn echo_char(&mut self, c: u8, termios: &RwLockReadGuard<Termios>) { 84352da9a59SGnoCiYeH if c == EchoOperation::Start.to_u8() { 84452da9a59SGnoCiYeH self.add_echo_byte(EchoOperation::Start.to_u8()); 84552da9a59SGnoCiYeH self.add_echo_byte(EchoOperation::Start.to_u8()); 84652da9a59SGnoCiYeH } else { 84752da9a59SGnoCiYeH if termios.local_mode.contains(LocalMode::ECHOCTL) 84852da9a59SGnoCiYeH && (c as char).is_control() 84952da9a59SGnoCiYeH && c != b'\t' 85052da9a59SGnoCiYeH { 85152da9a59SGnoCiYeH self.add_echo_byte(EchoOperation::Start.to_u8()); 85252da9a59SGnoCiYeH } 85352da9a59SGnoCiYeH self.add_echo_byte(c); 85452da9a59SGnoCiYeH } 85552da9a59SGnoCiYeH } 85652da9a59SGnoCiYeH 85752da9a59SGnoCiYeH pub fn echo_char_raw(&mut self, c: u8) { 85852da9a59SGnoCiYeH if c == EchoOperation::Start.to_u8() { 85952da9a59SGnoCiYeH self.add_echo_byte(EchoOperation::Start.to_u8()); 86052da9a59SGnoCiYeH self.add_echo_byte(EchoOperation::Start.to_u8()); 86152da9a59SGnoCiYeH } else { 86252da9a59SGnoCiYeH self.add_echo_byte(c); 86352da9a59SGnoCiYeH } 86452da9a59SGnoCiYeH } 86552da9a59SGnoCiYeH 86652da9a59SGnoCiYeH /// ## 提交echobuf里的数据显示 86752da9a59SGnoCiYeH pub fn commit_echoes(&mut self, tty: Arc<TtyCore>) { 86852da9a59SGnoCiYeH let head = self.echo_head; 86952da9a59SGnoCiYeH self.echo_mark = head; 87052da9a59SGnoCiYeH let old = self.echo_commit - self.echo_tail; 87152da9a59SGnoCiYeH 87252da9a59SGnoCiYeH // 需要echo的字符个数 87352da9a59SGnoCiYeH let nr = head - self.echo_tail; 87452da9a59SGnoCiYeH 87552da9a59SGnoCiYeH if nr < ECHO_COMMIT_WATERMARK || nr % ECHO_BLOCK > old % ECHO_BLOCK { 87652da9a59SGnoCiYeH return; 87752da9a59SGnoCiYeH } 87852da9a59SGnoCiYeH 87952da9a59SGnoCiYeH self.echo_commit = head; 88052da9a59SGnoCiYeH let echoed = self.echoes(tty.clone()); 88152da9a59SGnoCiYeH 88252da9a59SGnoCiYeH if echoed.is_ok() && echoed.unwrap() > 0 { 88352da9a59SGnoCiYeH tty.flush_chars(tty.core()); 88452da9a59SGnoCiYeH } 88552da9a59SGnoCiYeH } 88652da9a59SGnoCiYeH 88752da9a59SGnoCiYeH pub fn add_echo_byte(&mut self, c: u8) { 88852da9a59SGnoCiYeH self.echo_buf[ntty_buf_mask(self.echo_head)] = c; 88952da9a59SGnoCiYeH self.echo_head += 1; 89052da9a59SGnoCiYeH } 89152da9a59SGnoCiYeH 89252da9a59SGnoCiYeH pub fn add_read_byte(&mut self, c: u8) { 89352da9a59SGnoCiYeH self.read_buf[ntty_buf_mask(self.read_head)] = c; 89452da9a59SGnoCiYeH self.read_head += 1; 89552da9a59SGnoCiYeH } 89652da9a59SGnoCiYeH 89752da9a59SGnoCiYeH /// ### 将read_buffer的部分值置0 89852da9a59SGnoCiYeH /// 89952da9a59SGnoCiYeH /// 只会在规范模式和禁用echo下执行 90052da9a59SGnoCiYeH #[inline] 90152da9a59SGnoCiYeH pub fn zero_buffer(&mut self, offset: usize, size: usize) { 90252da9a59SGnoCiYeH let offset = offset & (NTTY_BUFSIZE - 1); 90352da9a59SGnoCiYeH if self.icanon && !self.echo { 90452da9a59SGnoCiYeH let n = offset + size; 90552da9a59SGnoCiYeH if n > NTTY_BUFSIZE { 90652da9a59SGnoCiYeH for c in &mut self.read_buf[offset..NTTY_BUFSIZE] { 90752da9a59SGnoCiYeH *c = 0 90852da9a59SGnoCiYeH } 90952da9a59SGnoCiYeH 91052da9a59SGnoCiYeH for c in &mut self.read_buf[0..(n - NTTY_BUFSIZE)] { 91152da9a59SGnoCiYeH *c = 0 91252da9a59SGnoCiYeH } 91352da9a59SGnoCiYeH } else { 91452da9a59SGnoCiYeH for c in &mut self.read_buf[offset..n] { 91552da9a59SGnoCiYeH *c = 0 91652da9a59SGnoCiYeH } 91752da9a59SGnoCiYeH }; 91852da9a59SGnoCiYeH } 91952da9a59SGnoCiYeH } 92052da9a59SGnoCiYeH 92152da9a59SGnoCiYeH /// ## 从ntty中拷贝数据 92252da9a59SGnoCiYeH /// 92352da9a59SGnoCiYeH /// ### 参数 92452da9a59SGnoCiYeH /// 92552da9a59SGnoCiYeH /// ### to: 存储数据 92652da9a59SGnoCiYeH /// ### tail: 读取尾 92752da9a59SGnoCiYeH pub fn ntty_copy( 92852da9a59SGnoCiYeH &mut self, 92952da9a59SGnoCiYeH to: &mut [u8], 93052da9a59SGnoCiYeH tail: usize, 93152da9a59SGnoCiYeH n: &mut usize, 93252da9a59SGnoCiYeH ) -> Result<(), SystemError> { 93352da9a59SGnoCiYeH if to.len() < *n { 93452da9a59SGnoCiYeH *n = to.len(); 93552da9a59SGnoCiYeH // return Err(SystemError::EINVAL); 93652da9a59SGnoCiYeH } 93752da9a59SGnoCiYeH if tail > NTTY_BUFSIZE { 93852da9a59SGnoCiYeH return Err(SystemError::EINVAL); 93952da9a59SGnoCiYeH } 94052da9a59SGnoCiYeH 94152da9a59SGnoCiYeH let size = NTTY_BUFSIZE - tail; 94252da9a59SGnoCiYeH 94352da9a59SGnoCiYeH if size < *n { 94452da9a59SGnoCiYeH // 有一部分数据在头部,则先拷贝后面部分,再拷贝头部 94552da9a59SGnoCiYeH // TODO: tty审计? 94652da9a59SGnoCiYeH to[0..size].copy_from_slice(&self.read_buf[tail..(tail + size)]); 94752bcb59eSGnoCiYeH to[size..(*n)].copy_from_slice(&self.read_buf[0..(*n - size)]); 94852da9a59SGnoCiYeH } else { 94952da9a59SGnoCiYeH to[..*n].copy_from_slice(&self.read_buf[tail..(tail + *n)]) 95052da9a59SGnoCiYeH } 95152da9a59SGnoCiYeH 95252da9a59SGnoCiYeH self.zero_buffer(tail, *n); 95352da9a59SGnoCiYeH 95452da9a59SGnoCiYeH Ok(()) 95552da9a59SGnoCiYeH } 95652da9a59SGnoCiYeH 95752da9a59SGnoCiYeH /// ## 规范模式下跳过EOF 95852da9a59SGnoCiYeH pub fn canon_skip_eof(&mut self) { 95952da9a59SGnoCiYeH // 没有数据 96052da9a59SGnoCiYeH if self.read_tail == self.canon_head { 96152da9a59SGnoCiYeH return; 96252da9a59SGnoCiYeH } 96352da9a59SGnoCiYeH 96452da9a59SGnoCiYeH let tail = self.read_tail & (NTTY_BUFSIZE - 1); 96552da9a59SGnoCiYeH 96652da9a59SGnoCiYeH // 查看read_flags是否读取位置为特殊字符 96752da9a59SGnoCiYeH if !self.read_flags.get(tail).unwrap() { 96852da9a59SGnoCiYeH return; 96952da9a59SGnoCiYeH } 97052da9a59SGnoCiYeH 97152da9a59SGnoCiYeH // 确保读取位置是'\0'字符 97252da9a59SGnoCiYeH if self.read_buf[tail] != ControlCharIndex::DISABLE_CHAR { 97352da9a59SGnoCiYeH return; 97452da9a59SGnoCiYeH } 97552da9a59SGnoCiYeH 97652da9a59SGnoCiYeH // 处理该字符,将read_flagsw该位清除 97752da9a59SGnoCiYeH self.read_flags.set(tail, false); 97852da9a59SGnoCiYeH // 读取位置+1,即跳过该字符不做处理 97952da9a59SGnoCiYeH self.read_tail += 1; 98052da9a59SGnoCiYeH } 98152da9a59SGnoCiYeH 98252da9a59SGnoCiYeH /// ## 在规范模式(canonical mode)下从读缓冲中复制一行 98352da9a59SGnoCiYeH /// 98452da9a59SGnoCiYeH /// 一次只拷贝一行 98552da9a59SGnoCiYeH /// 98652da9a59SGnoCiYeH /// ## 参数 98752da9a59SGnoCiYeH /// ### dst: 存放数据 98852da9a59SGnoCiYeH /// ### nr: 需要拷贝的数据大小 98952da9a59SGnoCiYeH /// 99052da9a59SGnoCiYeH /// ## 返回值 99152da9a59SGnoCiYeH /// ### true: 表示一行未结束并且还有数据可读 99252da9a59SGnoCiYeH /// ### false: 一行已结束或者没有数据可读 99352da9a59SGnoCiYeH pub fn canon_copy_from_read_buf( 99452da9a59SGnoCiYeH &mut self, 99552da9a59SGnoCiYeH dst: &mut [u8], 99652da9a59SGnoCiYeH nr: &mut usize, 99752da9a59SGnoCiYeH offset: &mut usize, 99852da9a59SGnoCiYeH ) -> Result<bool, SystemError> { 99952da9a59SGnoCiYeH if *nr == 0 { 100052da9a59SGnoCiYeH return Ok(false); 100152da9a59SGnoCiYeH } 100252da9a59SGnoCiYeH 100352da9a59SGnoCiYeH let canon_head = self.canon_head; 100452da9a59SGnoCiYeH 100552da9a59SGnoCiYeH // 取得能够读到的字符数,即canon_head - self.read_tail和nr最小值 100652da9a59SGnoCiYeH let mut n = (*nr).min(canon_head - self.read_tail); 100752da9a59SGnoCiYeH 100852da9a59SGnoCiYeH // 获得读尾index 100952da9a59SGnoCiYeH let tail = self.read_tail & (NTTY_BUFSIZE - 1); 101052da9a59SGnoCiYeH 101152da9a59SGnoCiYeH // 避免越界,这个size才是实际读取大小 101252da9a59SGnoCiYeH let size = if tail + n > NTTY_BUFSIZE { 101352da9a59SGnoCiYeH NTTY_BUFSIZE 101452da9a59SGnoCiYeH } else { 101552bcb59eSGnoCiYeH tail + n 101652da9a59SGnoCiYeH }; 101752da9a59SGnoCiYeH 101852da9a59SGnoCiYeH // 找到eol的坐标 101952da9a59SGnoCiYeH let tmp = self.read_flags.next_index(tail); 102052da9a59SGnoCiYeH // 找到的话即为坐标,未找到的话即为NTTY_BUFSIZE 1021*b5b571e0SLoGin let mut eol = if let Some(tmp) = tmp { tmp } else { size }; 102252da9a59SGnoCiYeH if eol > size { 102352da9a59SGnoCiYeH eol = size 102452da9a59SGnoCiYeH } 102552da9a59SGnoCiYeH 102652da9a59SGnoCiYeH // 是否需要绕回缓冲区头部 102752da9a59SGnoCiYeH let more = n - (size - tail); 102852da9a59SGnoCiYeH 102952da9a59SGnoCiYeH // 是否找到eol 103052da9a59SGnoCiYeH let found = if eol == NTTY_BUFSIZE && more > 0 { 103152da9a59SGnoCiYeH // 需要返回头部 103252da9a59SGnoCiYeH let ret = self.read_flags.first_index(); 1033*b5b571e0SLoGin if let Some(tmp) = ret { 103452da9a59SGnoCiYeH // 在头部范围内找到eol 103552da9a59SGnoCiYeH if tmp < more { 103652da9a59SGnoCiYeH eol = tmp; 103752da9a59SGnoCiYeH } 103852da9a59SGnoCiYeH } else { 103952da9a59SGnoCiYeH eol = more; 104052da9a59SGnoCiYeH } 104152da9a59SGnoCiYeH eol != more 104252da9a59SGnoCiYeH } else { 104352da9a59SGnoCiYeH // 不需要返回头部 104452da9a59SGnoCiYeH eol != size 104552da9a59SGnoCiYeH }; 104652da9a59SGnoCiYeH 104752da9a59SGnoCiYeH n = eol - tail; 104852da9a59SGnoCiYeH if n > NTTY_BUFSIZE { 104952da9a59SGnoCiYeH // 减法溢出则加上BUFSIZE即可限制在0-NTTY_BUFSIZE内 105052da9a59SGnoCiYeH n += NTTY_BUFSIZE; 105152da9a59SGnoCiYeH } 105252da9a59SGnoCiYeH 105352da9a59SGnoCiYeH // 规范模式下实际扫描过的字符数,需要将eol计算在内 105452da9a59SGnoCiYeH let count = if found { n + 1 } else { n }; 105552da9a59SGnoCiYeH 105652da9a59SGnoCiYeH // 表示这一行未结束 105752da9a59SGnoCiYeH if !found || self.read_at(eol) != ControlCharIndex::DISABLE_CHAR { 105852da9a59SGnoCiYeH n = count; 105952da9a59SGnoCiYeH } 106052da9a59SGnoCiYeH 106152da9a59SGnoCiYeH self.ntty_copy(&mut dst[*offset..], tail, &mut n)?; 106252da9a59SGnoCiYeH *nr -= n; 106352da9a59SGnoCiYeH *offset += n; 106452da9a59SGnoCiYeH 106552da9a59SGnoCiYeH if found { 106652da9a59SGnoCiYeH self.read_flags.set(eol, false); 106752da9a59SGnoCiYeH } 106852da9a59SGnoCiYeH 106952da9a59SGnoCiYeH self.read_tail += count; 107052da9a59SGnoCiYeH 107152da9a59SGnoCiYeH if found { 107252da9a59SGnoCiYeH if !self.pushing { 107352da9a59SGnoCiYeH self.line_start = self.read_tail; 107452da9a59SGnoCiYeH } else { 107552da9a59SGnoCiYeH self.pushing = false; 107652da9a59SGnoCiYeH } 107752da9a59SGnoCiYeH 107852da9a59SGnoCiYeH // todo: 审计? 107952da9a59SGnoCiYeH return Ok(false); 108052da9a59SGnoCiYeH } 108152da9a59SGnoCiYeH 108252da9a59SGnoCiYeH // 这里是表示没有找到eol,根据是否还有数据可读返回 108352da9a59SGnoCiYeH Ok(self.read_tail != canon_head) 108452da9a59SGnoCiYeH } 108552da9a59SGnoCiYeH 108652da9a59SGnoCiYeH /// ## 根据终端的模式和输入缓冲区中的数据量,判断是否可读字符 108752da9a59SGnoCiYeH pub fn input_available(&self, termios: RwLockReadGuard<Termios>, poll: bool) -> bool { 108852da9a59SGnoCiYeH // 计算最小字符数 108952da9a59SGnoCiYeH let amt = if poll 109052da9a59SGnoCiYeH && termios.control_characters[ControlCharIndex::VTIME] as u32 == 0 109152da9a59SGnoCiYeH && termios.control_characters[ControlCharIndex::VMIN] as u32 != 0 109252da9a59SGnoCiYeH { 109352da9a59SGnoCiYeH termios.control_characters[ControlCharIndex::VMIN] as usize 109452da9a59SGnoCiYeH } else { 109552da9a59SGnoCiYeH 1 109652da9a59SGnoCiYeH }; 109752da9a59SGnoCiYeH 109852da9a59SGnoCiYeH // 规范模式且非拓展 109952da9a59SGnoCiYeH if self.icanon && !termios.local_mode.contains(LocalMode::EXTPROC) { 110052da9a59SGnoCiYeH return self.canon_head != self.read_tail; 110152da9a59SGnoCiYeH } else { 110252da9a59SGnoCiYeH return (self.commit_head - self.read_tail) >= amt; 110352da9a59SGnoCiYeH } 110452da9a59SGnoCiYeH } 110552da9a59SGnoCiYeH 110652da9a59SGnoCiYeH /// ## 非规范模式下从read_buf读取数据 110752da9a59SGnoCiYeH /// 110852da9a59SGnoCiYeH /// ## 参数 110952da9a59SGnoCiYeH /// ### termios: tty对应的termioss读锁守卫 111052da9a59SGnoCiYeH /// ### dst: 存储读取数据 111152da9a59SGnoCiYeH /// ### nr: 读取长度 111252da9a59SGnoCiYeH /// 111352da9a59SGnoCiYeH /// ## 返回值 111452da9a59SGnoCiYeH /// ### true: 还有更多数据可读 111552da9a59SGnoCiYeH /// ### false: 无更多数据可读 111652da9a59SGnoCiYeH pub fn copy_from_read_buf( 111752da9a59SGnoCiYeH &mut self, 111852da9a59SGnoCiYeH termios: RwLockReadGuard<Termios>, 111952da9a59SGnoCiYeH dst: &mut [u8], 112052da9a59SGnoCiYeH nr: &mut usize, 112152da9a59SGnoCiYeH offset: &mut usize, 112252da9a59SGnoCiYeH ) -> Result<bool, SystemError> { 112352da9a59SGnoCiYeH let head = self.commit_head; 112452da9a59SGnoCiYeH let tail = self.read_tail & (NTTY_BUFSIZE - 1); 112552da9a59SGnoCiYeH 112652da9a59SGnoCiYeH // 计算出可读的字符数 112752bcb59eSGnoCiYeH let mut n = (NTTY_BUFSIZE - tail).min(head - self.read_tail); 112852da9a59SGnoCiYeH n = n.min(*nr); 112952da9a59SGnoCiYeH 113052da9a59SGnoCiYeH if n > 0 { 113152da9a59SGnoCiYeH // 拷贝数据 113252da9a59SGnoCiYeH self.ntty_copy(&mut dst[*offset..], tail, &mut n)?; 113352da9a59SGnoCiYeH // todo:审计? 113452da9a59SGnoCiYeH self.read_tail += n; 113552da9a59SGnoCiYeH 113652da9a59SGnoCiYeH // 是否只读取了eof 113752da9a59SGnoCiYeH let eof = 113852da9a59SGnoCiYeH n == 1 && self.read_buf[tail] == termios.control_characters[ControlCharIndex::VEOF]; 113952da9a59SGnoCiYeH 114052da9a59SGnoCiYeH if termios.local_mode.contains(LocalMode::EXTPROC) 114152da9a59SGnoCiYeH && self.icanon 114252da9a59SGnoCiYeH && eof 114352da9a59SGnoCiYeH && head == self.read_tail 114452da9a59SGnoCiYeH { 114552da9a59SGnoCiYeH return Ok(false); 114652da9a59SGnoCiYeH } 114752da9a59SGnoCiYeH 114852da9a59SGnoCiYeH *nr -= n; 114952da9a59SGnoCiYeH *offset += n; 115052da9a59SGnoCiYeH 115152da9a59SGnoCiYeH return Ok(head != self.read_tail); 115252da9a59SGnoCiYeH } 115352da9a59SGnoCiYeH 115452da9a59SGnoCiYeH Ok(false) 115552da9a59SGnoCiYeH } 115652da9a59SGnoCiYeH 115752da9a59SGnoCiYeH /// ## 用于处理带有 OPOST(Output Post-processing)标志的输出块的函数 115852da9a59SGnoCiYeH /// OPOST 是 POSIX 终端驱动器标志之一,用于指定在写入终端设备之前对输出数据进行一些后期处理。 115952da9a59SGnoCiYeH pub fn process_output_block( 116052da9a59SGnoCiYeH &mut self, 116152da9a59SGnoCiYeH core: &TtyCoreData, 116252da9a59SGnoCiYeH termios: RwLockReadGuard<Termios>, 116352da9a59SGnoCiYeH buf: &[u8], 116452da9a59SGnoCiYeH nr: usize, 116552da9a59SGnoCiYeH ) -> Result<usize, SystemError> { 116652da9a59SGnoCiYeH let mut nr = nr; 116752da9a59SGnoCiYeH let tty = self.tty.clone().unwrap().upgrade().unwrap(); 116852da9a59SGnoCiYeH let space = tty.write_room(tty.core()); 116952da9a59SGnoCiYeH 117052da9a59SGnoCiYeH // 如果读取数量大于了可用空间,则取最小的为真正的写入数量 117152da9a59SGnoCiYeH if nr > space { 117252da9a59SGnoCiYeH nr = space 117352da9a59SGnoCiYeH } 117452da9a59SGnoCiYeH 117552da9a59SGnoCiYeH let mut cnt = 0; 1176*b5b571e0SLoGin for (i, c) in buf.iter().enumerate().take(nr) { 117752da9a59SGnoCiYeH cnt = i; 1178*b5b571e0SLoGin let c = *c; 117952da9a59SGnoCiYeH if c as usize == 8 { 118052da9a59SGnoCiYeH // 表示退格 118152da9a59SGnoCiYeH if self.cursor_column > 0 { 118252da9a59SGnoCiYeH self.cursor_column -= 1; 118352da9a59SGnoCiYeH } 118452da9a59SGnoCiYeH continue; 118552da9a59SGnoCiYeH } 118652da9a59SGnoCiYeH match c as char { 118752da9a59SGnoCiYeH '\n' => { 118852da9a59SGnoCiYeH if termios.output_mode.contains(OutputMode::ONLRET) { 118952da9a59SGnoCiYeH // 将回车映射为\n,即将\n换为回车 119052da9a59SGnoCiYeH self.cursor_column = 0; 119152da9a59SGnoCiYeH } 119252da9a59SGnoCiYeH if termios.output_mode.contains(OutputMode::ONLCR) { 119352da9a59SGnoCiYeH // 输出时将\n换为\r\n 119452da9a59SGnoCiYeH break; 119552da9a59SGnoCiYeH } 119652da9a59SGnoCiYeH 119752da9a59SGnoCiYeH self.canon_cursor_column = self.cursor_column; 119852da9a59SGnoCiYeH } 119952da9a59SGnoCiYeH '\r' => { 120052da9a59SGnoCiYeH if termios.output_mode.contains(OutputMode::ONOCR) && self.cursor_column == 0 { 120152da9a59SGnoCiYeH // 光标已经在第0列,则不输出回车符 120252da9a59SGnoCiYeH break; 120352da9a59SGnoCiYeH } 120452da9a59SGnoCiYeH 120552da9a59SGnoCiYeH if termios.output_mode.contains(OutputMode::OCRNL) { 120652da9a59SGnoCiYeH break; 120752da9a59SGnoCiYeH } 120852da9a59SGnoCiYeH self.canon_cursor_column = self.cursor_column; 120952da9a59SGnoCiYeH } 121052da9a59SGnoCiYeH '\t' => { 121152da9a59SGnoCiYeH break; 121252da9a59SGnoCiYeH } 121352da9a59SGnoCiYeH _ => { 121452da9a59SGnoCiYeH // 判断是否为控制字符 121552da9a59SGnoCiYeH if !(c as char).is_control() { 121652da9a59SGnoCiYeH if termios.output_mode.contains(OutputMode::OLCUC) { 121752da9a59SGnoCiYeH break; 121852da9a59SGnoCiYeH } 121952da9a59SGnoCiYeH 122052da9a59SGnoCiYeH // 判断是否为utf8模式下的连续字符 122152da9a59SGnoCiYeH if !(termios.input_mode.contains(InputMode::IUTF8) 122252da9a59SGnoCiYeH && (c as usize) & 0xc0 == 0x80) 122352da9a59SGnoCiYeH { 122452da9a59SGnoCiYeH self.cursor_column += 1; 122552da9a59SGnoCiYeH } 122652da9a59SGnoCiYeH } 122752da9a59SGnoCiYeH } 122852da9a59SGnoCiYeH } 122952da9a59SGnoCiYeH } 123052da9a59SGnoCiYeH 123152da9a59SGnoCiYeH drop(termios); 123252da9a59SGnoCiYeH return tty.write(core, buf, cnt); 123352da9a59SGnoCiYeH } 123452da9a59SGnoCiYeH 123552da9a59SGnoCiYeH /// ## 处理回显 123652da9a59SGnoCiYeH pub fn process_echoes(&mut self, tty: Arc<TtyCore>) { 123752da9a59SGnoCiYeH if self.echo_mark == self.echo_tail { 123852da9a59SGnoCiYeH return; 123952da9a59SGnoCiYeH } 124052da9a59SGnoCiYeH self.echo_commit = self.echo_mark; 124152da9a59SGnoCiYeH let echoed = self.echoes(tty.clone()); 124252da9a59SGnoCiYeH 124352da9a59SGnoCiYeH if echoed.is_ok() && echoed.unwrap() > 0 { 1244*b5b571e0SLoGin tty.flush_chars(tty.core()); 124552da9a59SGnoCiYeH } 124652da9a59SGnoCiYeH } 124752da9a59SGnoCiYeH 124852bcb59eSGnoCiYeH #[inline(never)] 124952da9a59SGnoCiYeH pub fn echoes(&mut self, tty: Arc<TtyCore>) -> Result<usize, SystemError> { 125052da9a59SGnoCiYeH let mut space = tty.write_room(tty.core()); 125152da9a59SGnoCiYeH let ospace = space; 125252da9a59SGnoCiYeH let termios = tty.core().termios(); 125352da9a59SGnoCiYeH let core = tty.core(); 125452da9a59SGnoCiYeH let mut tail = self.echo_tail; 125552da9a59SGnoCiYeH 125652da9a59SGnoCiYeH while ntty_buf_mask(self.echo_commit) != ntty_buf_mask(tail) { 125752da9a59SGnoCiYeH let c = self.echo_buf[ntty_buf_mask(tail)]; 125852da9a59SGnoCiYeH 125952da9a59SGnoCiYeH if EchoOperation::from_u8(c) == EchoOperation::Start { 126052da9a59SGnoCiYeH if ntty_buf_mask(self.echo_commit) == ntty_buf_mask(tail + 1) { 126152da9a59SGnoCiYeH self.echo_tail = tail; 126252da9a59SGnoCiYeH return Ok(ospace - space); 126352da9a59SGnoCiYeH } 126452da9a59SGnoCiYeH 126552da9a59SGnoCiYeH // 获取到start,之后取第一个作为op 126652da9a59SGnoCiYeH let op = EchoOperation::from_u8(self.echo_buf[ntty_buf_mask(tail + 1)]); 126752da9a59SGnoCiYeH 126852da9a59SGnoCiYeH match op { 126952da9a59SGnoCiYeH EchoOperation::Start => { 127052da9a59SGnoCiYeH if space == 0 { 127152da9a59SGnoCiYeH break; 127252da9a59SGnoCiYeH } 127352da9a59SGnoCiYeH 127452da9a59SGnoCiYeH if tty 127552da9a59SGnoCiYeH .put_char(tty.core(), EchoOperation::Start.to_u8()) 127652da9a59SGnoCiYeH .is_err() 127752da9a59SGnoCiYeH { 127852da9a59SGnoCiYeH tty.write(core, &[EchoOperation::Start.to_u8()], 1)?; 127952da9a59SGnoCiYeH } 128052da9a59SGnoCiYeH 128152da9a59SGnoCiYeH self.cursor_column += 1; 128252da9a59SGnoCiYeH space -= 1; 128352da9a59SGnoCiYeH tail += 2; 128452da9a59SGnoCiYeH } 128552da9a59SGnoCiYeH EchoOperation::MoveBackCol => { 128652da9a59SGnoCiYeH if self.cursor_column > 0 { 128752da9a59SGnoCiYeH self.cursor_column -= 1; 128852da9a59SGnoCiYeH } 128952da9a59SGnoCiYeH tail += 2; 129052da9a59SGnoCiYeH } 129152da9a59SGnoCiYeH EchoOperation::SetCanonCol => { 129252da9a59SGnoCiYeH self.canon_cursor_column = self.cursor_column; 129352da9a59SGnoCiYeH tail += 2; 129452da9a59SGnoCiYeH } 129552da9a59SGnoCiYeH EchoOperation::EraseTab => { 129652da9a59SGnoCiYeH if ntty_buf_mask(self.echo_commit) == ntty_buf_mask(tail + 2) { 129752da9a59SGnoCiYeH self.echo_tail = tail; 129852da9a59SGnoCiYeH return Ok(ospace - space); 129952da9a59SGnoCiYeH } 130052da9a59SGnoCiYeH 130152da9a59SGnoCiYeH // 要擦除的制表符所占用的列数 130252da9a59SGnoCiYeH let mut char_num = self.echo_buf[ntty_buf_mask(tail + 2)] as usize; 130352da9a59SGnoCiYeH 130452da9a59SGnoCiYeH /* 130552da9a59SGnoCiYeH 如果 num_chars 的最高位(0x80)未设置, 130652da9a59SGnoCiYeH 表示这是从输入的起始位置而不是从先前的制表符开始计算的列数。 130752da9a59SGnoCiYeH 在这种情况下,将 num_chars 与 ldata->canon_column 相加,否则,列数就是正常的制表符列数。 130852da9a59SGnoCiYeH */ 130952da9a59SGnoCiYeH if char_num & 0x80 == 0 { 131052da9a59SGnoCiYeH char_num += self.canon_cursor_column as usize; 131152da9a59SGnoCiYeH } 131252da9a59SGnoCiYeH 131352da9a59SGnoCiYeH // 计算要回退的列数,即制表符宽度减去实际占用的列数 131452da9a59SGnoCiYeH let mut num_bs = 8 - (char_num & 7); 131552da9a59SGnoCiYeH if num_bs > space { 131652da9a59SGnoCiYeH // 表示左边没有足够空间回退 131752da9a59SGnoCiYeH break; 131852da9a59SGnoCiYeH } 131952da9a59SGnoCiYeH 132052da9a59SGnoCiYeH space -= num_bs; 132152da9a59SGnoCiYeH while num_bs != 0 { 132252da9a59SGnoCiYeH num_bs -= 1; 132352da9a59SGnoCiYeH // 8 => '\b' 132452da9a59SGnoCiYeH if tty.put_char(tty.core(), 8).is_err() { 132552da9a59SGnoCiYeH tty.write(core, &[8], 1)?; 132652da9a59SGnoCiYeH } 132752da9a59SGnoCiYeH 132852da9a59SGnoCiYeH if self.cursor_column > 0 { 132952da9a59SGnoCiYeH self.cursor_column -= 1; 133052da9a59SGnoCiYeH } 133152da9a59SGnoCiYeH } 133252da9a59SGnoCiYeH 133352da9a59SGnoCiYeH // 已经读取了 tail tail+1 tail+2,所以这里偏移加3 133452da9a59SGnoCiYeH tail += 3; 133552da9a59SGnoCiYeH } 133652da9a59SGnoCiYeH EchoOperation::Undefined(ch) => { 133752da9a59SGnoCiYeH match ch { 133852da9a59SGnoCiYeH 8 => { 133952da9a59SGnoCiYeH if tty.put_char(tty.core(), 8).is_err() { 134052da9a59SGnoCiYeH tty.write(core, &[8], 1)?; 134152da9a59SGnoCiYeH } 1342*b5b571e0SLoGin if tty.put_char(tty.core(), b' ').is_err() { 1343*b5b571e0SLoGin tty.write(core, &[b' '], 1)?; 134452da9a59SGnoCiYeH } 134552da9a59SGnoCiYeH self.cursor_column -= 1; 134652da9a59SGnoCiYeH space -= 1; 134752da9a59SGnoCiYeH tail += 1; 134852da9a59SGnoCiYeH } 134952da9a59SGnoCiYeH _ => { 135052da9a59SGnoCiYeH // 不是特殊字节码,则表示控制字符 例如 ^C 135152da9a59SGnoCiYeH if space < 2 { 135252da9a59SGnoCiYeH break; 135352da9a59SGnoCiYeH } 135452da9a59SGnoCiYeH 135552da9a59SGnoCiYeH if tty.put_char(tty.core(), b'^').is_err() { 135652da9a59SGnoCiYeH tty.write(core, &[b'^'], 1)?; 135752da9a59SGnoCiYeH } 135852da9a59SGnoCiYeH 135952da9a59SGnoCiYeH if tty.put_char(tty.core(), ch ^ 0o100).is_err() { 136052da9a59SGnoCiYeH tty.write(core, &[ch ^ 0o100], 1)?; 136152da9a59SGnoCiYeH } 136252da9a59SGnoCiYeH 136352da9a59SGnoCiYeH self.cursor_column += 2; 136452da9a59SGnoCiYeH space -= 2; 136552da9a59SGnoCiYeH tail += 2; 136652da9a59SGnoCiYeH } 136752da9a59SGnoCiYeH } 136852da9a59SGnoCiYeH } 136952da9a59SGnoCiYeH } 137052da9a59SGnoCiYeH } else { 137152da9a59SGnoCiYeH if termios.output_mode.contains(OutputMode::OPOST) { 137252da9a59SGnoCiYeH let ret = self.do_output_char(tty.clone(), c, space); 137352da9a59SGnoCiYeH 137452da9a59SGnoCiYeH if ret.is_err() { 137552da9a59SGnoCiYeH break; 137652da9a59SGnoCiYeH } 137752da9a59SGnoCiYeH space -= ret.unwrap(); 137852da9a59SGnoCiYeH } else { 137952da9a59SGnoCiYeH if space == 0 { 138052da9a59SGnoCiYeH break; 138152da9a59SGnoCiYeH } 138252da9a59SGnoCiYeH 138352da9a59SGnoCiYeH if tty.put_char(tty.core(), c).is_err() { 138452da9a59SGnoCiYeH tty.write(core, &[c], 1)?; 138552da9a59SGnoCiYeH } 138652da9a59SGnoCiYeH space -= 1; 138752da9a59SGnoCiYeH } 138852da9a59SGnoCiYeH tail += 1; 138952da9a59SGnoCiYeH } 139052da9a59SGnoCiYeH } 139152da9a59SGnoCiYeH 139252da9a59SGnoCiYeH // 如果回显缓冲区接近满(在下一次提交之前可能会发生回显溢出的情况),则丢弃足够的尾部数据以防止随后的溢出。 139352da9a59SGnoCiYeH while self.echo_commit > tail && self.echo_commit - tail >= ECHO_DISCARD_WATERMARK { 139452da9a59SGnoCiYeH if self.echo_buf[ntty_buf_mask(tail)] == EchoOperation::Start.to_u8() { 139552da9a59SGnoCiYeH if self.echo_buf[ntty_buf_mask(tail + 1)] == EchoOperation::EraseTab.to_u8() { 139652da9a59SGnoCiYeH tail += 3; 139752da9a59SGnoCiYeH } else { 139852da9a59SGnoCiYeH tail += 2; 139952da9a59SGnoCiYeH } 140052da9a59SGnoCiYeH } else { 140152da9a59SGnoCiYeH tail += 1; 140252da9a59SGnoCiYeH } 140352da9a59SGnoCiYeH } 140452da9a59SGnoCiYeH 140552da9a59SGnoCiYeH self.echo_tail = tail; 140652da9a59SGnoCiYeH return Ok(ospace - space); 140752da9a59SGnoCiYeH } 140852da9a59SGnoCiYeH 140952da9a59SGnoCiYeH /// ## 处理输出字符(带有 OPOST 处理) 141052da9a59SGnoCiYeH pub fn process_output(&mut self, tty: Arc<TtyCore>, c: u8) -> bool { 141152da9a59SGnoCiYeH let space = tty.write_room(tty.core()); 141252da9a59SGnoCiYeH 141352da9a59SGnoCiYeH if self.do_output_char(tty, c, space).is_err() { 141452da9a59SGnoCiYeH return false; 141552da9a59SGnoCiYeH } 141652da9a59SGnoCiYeH 141752da9a59SGnoCiYeH true 141852da9a59SGnoCiYeH } 141952da9a59SGnoCiYeH 142052da9a59SGnoCiYeH // ## 设置带有 OPOST 处理的tty输出一个字符 142152da9a59SGnoCiYeH pub fn do_output_char( 142252da9a59SGnoCiYeH &mut self, 142352da9a59SGnoCiYeH tty: Arc<TtyCore>, 142452da9a59SGnoCiYeH c: u8, 142552da9a59SGnoCiYeH space: usize, 142652da9a59SGnoCiYeH ) -> Result<usize, SystemError> { 142752da9a59SGnoCiYeH if space == 0 { 142852da9a59SGnoCiYeH return Err(SystemError::ENOBUFS); 142952da9a59SGnoCiYeH } 143052da9a59SGnoCiYeH 143152da9a59SGnoCiYeH let termios = tty.core().termios(); 143252da9a59SGnoCiYeH let core = tty.core(); 143352da9a59SGnoCiYeH let mut c = c; 143452da9a59SGnoCiYeH if c as usize == 8 { 143552da9a59SGnoCiYeH // 表示退格 143652da9a59SGnoCiYeH if self.cursor_column > 0 { 143752da9a59SGnoCiYeH self.cursor_column -= 1; 143852da9a59SGnoCiYeH } 143952da9a59SGnoCiYeH if tty.put_char(tty.core(), c).is_err() { 144052da9a59SGnoCiYeH tty.write(core, &[c], 1)?; 144152da9a59SGnoCiYeH } 144252da9a59SGnoCiYeH return Ok(1); 144352da9a59SGnoCiYeH } 144452da9a59SGnoCiYeH match c as char { 144552da9a59SGnoCiYeH '\n' => { 144652da9a59SGnoCiYeH if termios.output_mode.contains(OutputMode::ONLRET) { 144752da9a59SGnoCiYeH // 回车符 144852da9a59SGnoCiYeH self.cursor_column = 0; 144952da9a59SGnoCiYeH } 145052da9a59SGnoCiYeH if termios.output_mode.contains(OutputMode::ONLCR) { 145152da9a59SGnoCiYeH // 映射为“\r\n” 145252da9a59SGnoCiYeH if space < 2 { 145352da9a59SGnoCiYeH return Err(SystemError::ENOBUFS); 145452da9a59SGnoCiYeH } 145552da9a59SGnoCiYeH self.cursor_column = 0; 145652da9a59SGnoCiYeH self.canon_cursor_column = 0; 145752da9a59SGnoCiYeH 145852da9a59SGnoCiYeH // 通过驱动写入 145952da9a59SGnoCiYeH tty.write(core, "\r\n".as_bytes(), 2)?; 146052da9a59SGnoCiYeH return Ok(2); 146152da9a59SGnoCiYeH } 146252da9a59SGnoCiYeH 146352da9a59SGnoCiYeH self.canon_cursor_column = self.cursor_column; 146452da9a59SGnoCiYeH } 146552da9a59SGnoCiYeH '\r' => { 146652da9a59SGnoCiYeH if termios.output_mode.contains(OutputMode::ONOCR) && self.cursor_column == 0 { 146752da9a59SGnoCiYeH // 光标已经在第0列,则不输出回车符 146852da9a59SGnoCiYeH return Ok(0); 146952da9a59SGnoCiYeH } 147052da9a59SGnoCiYeH 147152da9a59SGnoCiYeH if termios.output_mode.contains(OutputMode::OCRNL) { 147252da9a59SGnoCiYeH // 输出的\r映射为\n 147352da9a59SGnoCiYeH c = b'\n'; 147452da9a59SGnoCiYeH if termios.output_mode.contains(OutputMode::ONLRET) { 147552da9a59SGnoCiYeH // \r映射为\n,但是保留\r特性 147652da9a59SGnoCiYeH self.cursor_column = 0; 147752da9a59SGnoCiYeH self.canon_cursor_column = 0; 147852da9a59SGnoCiYeH } 147952da9a59SGnoCiYeH } else { 148052da9a59SGnoCiYeH self.cursor_column = 0; 148152da9a59SGnoCiYeH self.canon_cursor_column = 0; 148252da9a59SGnoCiYeH } 148352da9a59SGnoCiYeH } 148452da9a59SGnoCiYeH '\t' => { 148552da9a59SGnoCiYeH // 计算输出一个\t需要的空间 148652da9a59SGnoCiYeH let spaces = 8 - (self.cursor_column & 7) as usize; 1487*b5b571e0SLoGin if termios.output_mode.contains(OutputMode::TABDLY) 1488*b5b571e0SLoGin && OutputMode::TABDLY.bits() == OutputMode::XTABS.bits() 1489*b5b571e0SLoGin { 149052da9a59SGnoCiYeH // 配置的tab选项是真正输出空格到驱动 149152da9a59SGnoCiYeH if space < spaces { 149252da9a59SGnoCiYeH // 空间不够 149352da9a59SGnoCiYeH return Err(SystemError::ENOBUFS); 149452da9a59SGnoCiYeH } 149552da9a59SGnoCiYeH self.cursor_column += spaces as u32; 149652da9a59SGnoCiYeH // 写入sapces个空格 149752da9a59SGnoCiYeH tty.write(core, " ".as_bytes(), spaces)?; 149852da9a59SGnoCiYeH return Ok(spaces); 149952da9a59SGnoCiYeH } 150052da9a59SGnoCiYeH self.cursor_column += spaces as u32; 150152da9a59SGnoCiYeH } 150252da9a59SGnoCiYeH _ => { 150352da9a59SGnoCiYeH // 判断是否为控制字符 150452da9a59SGnoCiYeH if !(c as char).is_control() { 150552da9a59SGnoCiYeH if termios.output_mode.contains(OutputMode::OLCUC) { 150652da9a59SGnoCiYeH c = c.to_ascii_uppercase(); 150752da9a59SGnoCiYeH } 150852da9a59SGnoCiYeH 150952da9a59SGnoCiYeH // 判断是否为utf8模式下的连续字符 151052da9a59SGnoCiYeH if !(termios.input_mode.contains(InputMode::IUTF8) 151152da9a59SGnoCiYeH && (c as usize) & 0xc0 == 0x80) 151252da9a59SGnoCiYeH { 151352da9a59SGnoCiYeH self.cursor_column += 1; 151452da9a59SGnoCiYeH } 151552da9a59SGnoCiYeH } 151652da9a59SGnoCiYeH } 151752da9a59SGnoCiYeH } 151852da9a59SGnoCiYeH 151952da9a59SGnoCiYeH if tty.put_char(tty.core(), c).is_err() { 152052da9a59SGnoCiYeH tty.write(core, &[c], 1)?; 152152da9a59SGnoCiYeH } 152252da9a59SGnoCiYeH Ok(1) 152352da9a59SGnoCiYeH } 152452da9a59SGnoCiYeH } 152552da9a59SGnoCiYeH 152652da9a59SGnoCiYeH impl TtyLineDiscipline for NTtyLinediscipline { 152752da9a59SGnoCiYeH fn open(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> { 152852da9a59SGnoCiYeH // 反向绑定tty到disc 152952da9a59SGnoCiYeH self.disc_data().tty = Some(Arc::downgrade(&tty)); 153052da9a59SGnoCiYeH // 特定的tty设备在这里可能需要取消端口节流 153152da9a59SGnoCiYeH return self.set_termios(tty, None); 153252da9a59SGnoCiYeH } 153352da9a59SGnoCiYeH 153452da9a59SGnoCiYeH fn close(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> { 153552da9a59SGnoCiYeH todo!() 153652da9a59SGnoCiYeH } 153752da9a59SGnoCiYeH 153852da9a59SGnoCiYeH /// ## 重置缓冲区的基本信息 153952da9a59SGnoCiYeH fn flush_buffer(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> { 154052da9a59SGnoCiYeH let core = tty.core(); 154152da9a59SGnoCiYeH let _ = core.termios(); 154252da9a59SGnoCiYeH let mut ldata = self.disc_data(); 154352da9a59SGnoCiYeH ldata.read_head = 0; 154452da9a59SGnoCiYeH ldata.canon_head = 0; 154552da9a59SGnoCiYeH ldata.read_tail = 0; 154652da9a59SGnoCiYeH ldata.commit_head = 0; 154752da9a59SGnoCiYeH ldata.line_start = 0; 154852da9a59SGnoCiYeH ldata.erasing = false; 154952da9a59SGnoCiYeH ldata.read_flags.set_all(false); 155052da9a59SGnoCiYeH ldata.pushing = false; 155152da9a59SGnoCiYeH ldata.lookahead_count = 0; 155252da9a59SGnoCiYeH 155352da9a59SGnoCiYeH // todo: kick worker? 155452da9a59SGnoCiYeH // todo: packet mode? 155552da9a59SGnoCiYeH 155652da9a59SGnoCiYeH Ok(()) 155752da9a59SGnoCiYeH } 155852da9a59SGnoCiYeH 155952bcb59eSGnoCiYeH #[inline(never)] 156052da9a59SGnoCiYeH fn read( 156152da9a59SGnoCiYeH &self, 156252da9a59SGnoCiYeH tty: Arc<TtyCore>, 156352da9a59SGnoCiYeH buf: &mut [u8], 156452da9a59SGnoCiYeH len: usize, 156552da9a59SGnoCiYeH cookie: &mut bool, 156652da9a59SGnoCiYeH _offset: usize, 156752da9a59SGnoCiYeH mode: FileMode, 156852da9a59SGnoCiYeH ) -> Result<usize, system_error::SystemError> { 156952da9a59SGnoCiYeH let mut ldata; 157052da9a59SGnoCiYeH if mode.contains(FileMode::O_NONBLOCK) { 157152da9a59SGnoCiYeH let ret = self.disc_data_try_lock(); 157252da9a59SGnoCiYeH if ret.is_err() { 157352da9a59SGnoCiYeH return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 157452da9a59SGnoCiYeH } 157552da9a59SGnoCiYeH ldata = ret.unwrap(); 157652da9a59SGnoCiYeH } else { 157752da9a59SGnoCiYeH ldata = self.disc_data(); 157852da9a59SGnoCiYeH } 157952da9a59SGnoCiYeH let core = tty.core(); 158052da9a59SGnoCiYeH let termios = core.termios(); 158152da9a59SGnoCiYeH let mut nr = len; 158252da9a59SGnoCiYeH 158352da9a59SGnoCiYeH let mut offset = 0; 158452da9a59SGnoCiYeH 158552da9a59SGnoCiYeH // 表示接着读 158652da9a59SGnoCiYeH if *cookie { 158752da9a59SGnoCiYeH // 规范且非拓展模式 158852da9a59SGnoCiYeH if ldata.icanon && !termios.local_mode.contains(LocalMode::EXTPROC) { 158952da9a59SGnoCiYeH // 跳过EOF字符 159052da9a59SGnoCiYeH if len == 0 { 159152da9a59SGnoCiYeH ldata.canon_skip_eof(); 159252da9a59SGnoCiYeH } else if ldata.canon_copy_from_read_buf(buf, &mut nr, &mut offset)? { 159352da9a59SGnoCiYeH return Ok(len - nr); 159452da9a59SGnoCiYeH } 1595*b5b571e0SLoGin } else if ldata.copy_from_read_buf(termios, buf, &mut nr, &mut offset)? { 159652da9a59SGnoCiYeH return Ok(len - nr); 159752da9a59SGnoCiYeH } 159852da9a59SGnoCiYeH 159952da9a59SGnoCiYeH // 没有数据可读 160052da9a59SGnoCiYeH 160152da9a59SGnoCiYeH // todo: kick worker? or 关闭节流? 160252da9a59SGnoCiYeH 160352da9a59SGnoCiYeH *cookie = false; 160452da9a59SGnoCiYeH return Ok(len - nr); 160552da9a59SGnoCiYeH } 160652da9a59SGnoCiYeH 160752da9a59SGnoCiYeH drop(termios); 160852da9a59SGnoCiYeH 160952da9a59SGnoCiYeH TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTIN)?; 161052da9a59SGnoCiYeH 161152da9a59SGnoCiYeH let mut minimum: usize = 0; 161252da9a59SGnoCiYeH if !ldata.icanon { 161352da9a59SGnoCiYeH let core = tty.core(); 161452da9a59SGnoCiYeH let termios = core.termios(); 161552da9a59SGnoCiYeH minimum = termios.control_characters[ControlCharIndex::VMIN] as usize; 161652da9a59SGnoCiYeH if minimum == 0 { 161752da9a59SGnoCiYeH minimum = 1; 161852da9a59SGnoCiYeH } 161952da9a59SGnoCiYeH } 162052da9a59SGnoCiYeH 162152da9a59SGnoCiYeH let mut ret: Result<usize, SystemError> = Ok(0); 162252da9a59SGnoCiYeH // 记录读取前 的tail 162352da9a59SGnoCiYeH let tail = ldata.read_tail; 162452da9a59SGnoCiYeH drop(ldata); 162552da9a59SGnoCiYeH while nr != 0 { 162652da9a59SGnoCiYeH // todo: 处理packet模式 162752da9a59SGnoCiYeH let mut ldata = self.disc_data(); 162852da9a59SGnoCiYeH 162952da9a59SGnoCiYeH let core = tty.core(); 163052da9a59SGnoCiYeH if !ldata.input_available(core.termios(), false) { 163152da9a59SGnoCiYeH if core.flags().contains(TtyFlag::OTHER_CLOSED) { 163252da9a59SGnoCiYeH ret = Err(SystemError::EIO); 163352da9a59SGnoCiYeH break; 163452da9a59SGnoCiYeH } 163552da9a59SGnoCiYeH 163652da9a59SGnoCiYeH if core.flags().contains(TtyFlag::HUPPED) || core.flags().contains(TtyFlag::HUPPING) 163752da9a59SGnoCiYeH { 163852da9a59SGnoCiYeH break; 163952da9a59SGnoCiYeH } 164052da9a59SGnoCiYeH 164152da9a59SGnoCiYeH if mode.contains(FileMode::O_NONBLOCK) 164252da9a59SGnoCiYeH || core.flags().contains(TtyFlag::LDISC_CHANGING) 164352da9a59SGnoCiYeH { 164452da9a59SGnoCiYeH ret = Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 164552da9a59SGnoCiYeH break; 164652da9a59SGnoCiYeH } 164752da9a59SGnoCiYeH 164852da9a59SGnoCiYeH if ProcessManager::current_pcb() 164952bcb59eSGnoCiYeH .sig_info_irqsave() 165052da9a59SGnoCiYeH .sig_pending() 165152da9a59SGnoCiYeH .has_pending() 165252da9a59SGnoCiYeH { 165352da9a59SGnoCiYeH ret = Err(SystemError::ERESTARTSYS); 165452da9a59SGnoCiYeH break; 165552da9a59SGnoCiYeH } 165652da9a59SGnoCiYeH 165752da9a59SGnoCiYeH // 休眠一段时间 165852da9a59SGnoCiYeH // 获取到termios读锁,避免termios被更改导致行为异常 165952da9a59SGnoCiYeH // let termios = core.termios_preempt_enable(); 166052da9a59SGnoCiYeH // let helper = WakeUpHelper::new(ProcessManager::current_pcb()); 166152da9a59SGnoCiYeH // let wakeup_helper = Timer::new(helper, timeout); 166252da9a59SGnoCiYeH // wakeup_helper.activate(); 166352da9a59SGnoCiYeH // drop(termios); 166452da9a59SGnoCiYeH drop(ldata); 166552da9a59SGnoCiYeH core.read_wq() 166652da9a59SGnoCiYeH .sleep((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64); 166752da9a59SGnoCiYeH continue; 166852da9a59SGnoCiYeH } 166952da9a59SGnoCiYeH 167052da9a59SGnoCiYeH if ldata.icanon && !core.termios().local_mode.contains(LocalMode::EXTPROC) { 167152da9a59SGnoCiYeH if ldata.canon_copy_from_read_buf(buf, &mut nr, &mut offset)? { 167252da9a59SGnoCiYeH *cookie = true; 167352da9a59SGnoCiYeH offset += len - nr; 167452da9a59SGnoCiYeH return Ok(offset); 167552da9a59SGnoCiYeH } 167652da9a59SGnoCiYeH } else { 167752da9a59SGnoCiYeH // 非标准模式 167852da9a59SGnoCiYeH // todo: 处理packet模式 167952da9a59SGnoCiYeH 168052da9a59SGnoCiYeH // 拷贝数据 168152da9a59SGnoCiYeH if ldata.copy_from_read_buf(core.termios(), buf, &mut nr, &mut offset)? 168252da9a59SGnoCiYeH && offset >= minimum 168352da9a59SGnoCiYeH { 168452da9a59SGnoCiYeH *cookie = true; 168552da9a59SGnoCiYeH return Ok(offset); 168652da9a59SGnoCiYeH } 168752da9a59SGnoCiYeH } 168852da9a59SGnoCiYeH 168952da9a59SGnoCiYeH if offset >= minimum { 169052da9a59SGnoCiYeH break; 169152da9a59SGnoCiYeH } 169252da9a59SGnoCiYeH } 169352da9a59SGnoCiYeH let ldata = self.disc_data(); 169452da9a59SGnoCiYeH if tail != ldata.read_tail { 169552da9a59SGnoCiYeH // todo: kick worker? 169652da9a59SGnoCiYeH } 169752da9a59SGnoCiYeH 169852da9a59SGnoCiYeH if offset > 0 { 169952da9a59SGnoCiYeH return Ok(offset); 170052da9a59SGnoCiYeH } 170152da9a59SGnoCiYeH 170252da9a59SGnoCiYeH ret 170352da9a59SGnoCiYeH } 170452da9a59SGnoCiYeH 170552bcb59eSGnoCiYeH #[inline(never)] 170652da9a59SGnoCiYeH fn write( 170752da9a59SGnoCiYeH &self, 170852da9a59SGnoCiYeH tty: Arc<TtyCore>, 170952da9a59SGnoCiYeH buf: &[u8], 171052da9a59SGnoCiYeH len: usize, 171152da9a59SGnoCiYeH mode: FileMode, 171252da9a59SGnoCiYeH ) -> Result<usize, system_error::SystemError> { 171352da9a59SGnoCiYeH let mut nr = len; 171452da9a59SGnoCiYeH let mut ldata = self.disc_data(); 171552da9a59SGnoCiYeH let pcb = ProcessManager::current_pcb(); 171652da9a59SGnoCiYeH let binding = tty.clone(); 171752da9a59SGnoCiYeH let core = binding.core(); 1718*b5b571e0SLoGin let termios = *core.termios(); 171952da9a59SGnoCiYeH if termios.local_mode.contains(LocalMode::TOSTOP) { 172052da9a59SGnoCiYeH TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTOU)?; 172152da9a59SGnoCiYeH } 172252da9a59SGnoCiYeH 172352da9a59SGnoCiYeH ldata.process_echoes(tty.clone()); 172452da9a59SGnoCiYeH // drop(ldata); 172552da9a59SGnoCiYeH let mut offset = 0; 172652da9a59SGnoCiYeH loop { 172752bcb59eSGnoCiYeH if pcb.sig_info_irqsave().sig_pending().has_pending() { 172852da9a59SGnoCiYeH return Err(SystemError::ERESTARTSYS); 172952da9a59SGnoCiYeH } 173052da9a59SGnoCiYeH if core.flags().contains(TtyFlag::HUPPED) { 173152da9a59SGnoCiYeH return Err(SystemError::EIO); 173252da9a59SGnoCiYeH } 173352da9a59SGnoCiYeH if termios.output_mode.contains(OutputMode::OPOST) { 173452da9a59SGnoCiYeH while nr > 0 { 173552da9a59SGnoCiYeH // let mut ldata = self.disc_data(); 173652da9a59SGnoCiYeH // 获得一次处理后的数量 173752da9a59SGnoCiYeH let ret = ldata.process_output_block(core, core.termios(), &buf[offset..], nr); 173852da9a59SGnoCiYeH let num = match ret { 173952da9a59SGnoCiYeH Ok(num) => num, 174052da9a59SGnoCiYeH Err(e) => { 174152da9a59SGnoCiYeH if e == SystemError::EAGAIN_OR_EWOULDBLOCK { 174252da9a59SGnoCiYeH break; 174352da9a59SGnoCiYeH } else { 174452da9a59SGnoCiYeH return Err(e); 174552da9a59SGnoCiYeH } 174652da9a59SGnoCiYeH } 174752da9a59SGnoCiYeH }; 174852da9a59SGnoCiYeH 174952da9a59SGnoCiYeH offset += num; 175052da9a59SGnoCiYeH nr -= num; 175152da9a59SGnoCiYeH 175252da9a59SGnoCiYeH if nr == 0 { 175352da9a59SGnoCiYeH break; 175452da9a59SGnoCiYeH } 175552da9a59SGnoCiYeH 175652da9a59SGnoCiYeH let c = buf[offset]; 175752da9a59SGnoCiYeH if !ldata.process_output(tty.clone(), c) { 175852da9a59SGnoCiYeH break; 175952da9a59SGnoCiYeH } 176052da9a59SGnoCiYeH offset += 1; 176152da9a59SGnoCiYeH nr -= 1; 176252da9a59SGnoCiYeH } 176352da9a59SGnoCiYeH 1764*b5b571e0SLoGin tty.flush_chars(core); 176552da9a59SGnoCiYeH } else { 176652da9a59SGnoCiYeH while nr > 0 { 176752da9a59SGnoCiYeH let write = tty.write(core, &buf[offset..], nr)?; 176852da9a59SGnoCiYeH if write == 0 { 176952da9a59SGnoCiYeH break; 177052da9a59SGnoCiYeH } 177152da9a59SGnoCiYeH offset += write; 177252da9a59SGnoCiYeH nr -= write; 177352da9a59SGnoCiYeH } 177452da9a59SGnoCiYeH } 177552da9a59SGnoCiYeH 177652da9a59SGnoCiYeH if nr == 0 { 177752da9a59SGnoCiYeH break; 177852da9a59SGnoCiYeH } 177952da9a59SGnoCiYeH 178052da9a59SGnoCiYeH if mode.contains(FileMode::O_NONBLOCK) || core.flags().contains(TtyFlag::LDISC_CHANGING) 178152da9a59SGnoCiYeH { 178252da9a59SGnoCiYeH return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 178352da9a59SGnoCiYeH } 178452da9a59SGnoCiYeH 178552da9a59SGnoCiYeH // 到这里表明没位置可写了 178652da9a59SGnoCiYeH // 休眠一段时间 178752da9a59SGnoCiYeH // 获取到termios读锁,避免termios被更改导致行为异常 178852da9a59SGnoCiYeH core.write_wq() 178952da9a59SGnoCiYeH .sleep(EPollEventType::EPOLLOUT.bits() as u64); 179052da9a59SGnoCiYeH } 179152da9a59SGnoCiYeH 179252da9a59SGnoCiYeH Ok(offset) 179352da9a59SGnoCiYeH } 179452da9a59SGnoCiYeH 179552da9a59SGnoCiYeH fn ioctl( 179652da9a59SGnoCiYeH &self, 179752da9a59SGnoCiYeH tty: Arc<TtyCore>, 179852da9a59SGnoCiYeH cmd: u32, 179952da9a59SGnoCiYeH arg: usize, 180052da9a59SGnoCiYeH ) -> Result<usize, system_error::SystemError> { 180152da9a59SGnoCiYeH match cmd { 180252da9a59SGnoCiYeH TtyIoctlCmd::TIOCOUTQ => { 180352da9a59SGnoCiYeH let mut user_writer = UserBufferWriter::new( 180452da9a59SGnoCiYeH VirtAddr::new(arg).as_ptr::<i32>(), 180552da9a59SGnoCiYeH core::mem::size_of::<i32>(), 180652da9a59SGnoCiYeH true, 180752da9a59SGnoCiYeH )?; 180852da9a59SGnoCiYeH 180952da9a59SGnoCiYeH let count = tty.chars_in_buffer(); 181052da9a59SGnoCiYeH user_writer.copy_one_to_user::<i32>(&(count as i32), 0)?; 181152da9a59SGnoCiYeH return Ok(0); 181252da9a59SGnoCiYeH } 181352da9a59SGnoCiYeH TtyIoctlCmd::FIONREAD => { 181452da9a59SGnoCiYeH let ldata = self.disc_data(); 181552da9a59SGnoCiYeH let termios = tty.core().termios(); 181652da9a59SGnoCiYeH let retval; 181752da9a59SGnoCiYeH if termios.local_mode.contains(LocalMode::ICANON) 181852da9a59SGnoCiYeH && !termios.local_mode.contains(LocalMode::EXTPROC) 181952da9a59SGnoCiYeH { 182052da9a59SGnoCiYeH if ldata.canon_head == ldata.read_tail { 182152da9a59SGnoCiYeH retval = 0; 182252da9a59SGnoCiYeH } else { 182352da9a59SGnoCiYeH let head = ldata.canon_head; 182452da9a59SGnoCiYeH let mut tail = ldata.read_tail; 182552da9a59SGnoCiYeH let mut nr = head - tail; 182652da9a59SGnoCiYeH 182752da9a59SGnoCiYeH while ntty_buf_mask(head) != ntty_buf_mask(tail) { 182852da9a59SGnoCiYeH if ldata.read_flags.get(ntty_buf_mask(tail)).unwrap() 182952da9a59SGnoCiYeH && ldata.read_buf[ntty_buf_mask(tail)] 183052da9a59SGnoCiYeH == ControlCharIndex::DISABLE_CHAR 183152da9a59SGnoCiYeH { 183252da9a59SGnoCiYeH nr -= 1; 183352da9a59SGnoCiYeH } 183452da9a59SGnoCiYeH tail += 1; 183552da9a59SGnoCiYeH } 183652da9a59SGnoCiYeH 183752da9a59SGnoCiYeH retval = nr; 183852da9a59SGnoCiYeH } 183952da9a59SGnoCiYeH } else { 184052da9a59SGnoCiYeH retval = ldata.read_cnt(); 184152da9a59SGnoCiYeH } 184252da9a59SGnoCiYeH 184352da9a59SGnoCiYeH let mut user_writer = UserBufferWriter::new( 184452da9a59SGnoCiYeH VirtAddr::new(arg).as_ptr::<i32>(), 184552da9a59SGnoCiYeH core::mem::size_of::<i32>(), 184652da9a59SGnoCiYeH true, 184752da9a59SGnoCiYeH )?; 184852da9a59SGnoCiYeH 184952da9a59SGnoCiYeH user_writer.copy_one_to_user::<i32>(&(retval as i32), 0)?; 185052da9a59SGnoCiYeH return Ok(0); 185152da9a59SGnoCiYeH } 185252da9a59SGnoCiYeH _ => { 185352da9a59SGnoCiYeH return self.ioctl_helper(tty, cmd, arg); 185452da9a59SGnoCiYeH } 185552da9a59SGnoCiYeH } 185652da9a59SGnoCiYeH } 185752da9a59SGnoCiYeH 185852bcb59eSGnoCiYeH #[inline(never)] 185952da9a59SGnoCiYeH fn set_termios( 186052da9a59SGnoCiYeH &self, 186152da9a59SGnoCiYeH tty: Arc<TtyCore>, 186252da9a59SGnoCiYeH old: Option<crate::driver::tty::termios::Termios>, 186352da9a59SGnoCiYeH ) -> Result<(), system_error::SystemError> { 186452da9a59SGnoCiYeH let core = tty.core(); 186552da9a59SGnoCiYeH let termios = core.termios(); 186652da9a59SGnoCiYeH let mut ldata = self.disc_data(); 186752da9a59SGnoCiYeH let contorl_chars = termios.control_characters; 186852da9a59SGnoCiYeH 186952da9a59SGnoCiYeH // 第一次设置或者规范模式 (ICANON) 或者扩展处理 (EXTPROC) 标志发生变化 187052bcb59eSGnoCiYeH let mut spec_mode_changed = false; 1871*b5b571e0SLoGin if let Some(old) = old { 1872*b5b571e0SLoGin let local_mode = old.local_mode.bitxor(termios.local_mode); 187352bcb59eSGnoCiYeH spec_mode_changed = 187452bcb59eSGnoCiYeH local_mode.contains(LocalMode::ICANON) || local_mode.contains(LocalMode::EXTPROC); 187552bcb59eSGnoCiYeH } 187652bcb59eSGnoCiYeH if old.is_none() || spec_mode_changed { 187752da9a59SGnoCiYeH // 重置read_flags 187852da9a59SGnoCiYeH ldata.read_flags.set_all(false); 187952da9a59SGnoCiYeH 188052da9a59SGnoCiYeH ldata.line_start = ldata.read_tail; 188152da9a59SGnoCiYeH 188252da9a59SGnoCiYeH // 不是规范模式或者有可读数据 188352da9a59SGnoCiYeH if !termios.local_mode.contains(LocalMode::ICANON) || ldata.read_cnt() != 0 { 188452da9a59SGnoCiYeH ldata.canon_head = ldata.read_tail; 188552da9a59SGnoCiYeH ldata.pushing = false; 188652da9a59SGnoCiYeH } else { 188752da9a59SGnoCiYeH let read_head = ldata.read_head; 188852da9a59SGnoCiYeH ldata 188952da9a59SGnoCiYeH .read_flags 189052da9a59SGnoCiYeH .set((read_head - 1) & (NTTY_BUFSIZE - 1), true); 189152da9a59SGnoCiYeH ldata.canon_head = ldata.read_head; 189252da9a59SGnoCiYeH ldata.pushing = true; 189352da9a59SGnoCiYeH } 189452da9a59SGnoCiYeH ldata.commit_head = ldata.read_head; 189552da9a59SGnoCiYeH ldata.erasing = false; 189652da9a59SGnoCiYeH ldata.lnext = false; 189752da9a59SGnoCiYeH } 189852da9a59SGnoCiYeH 189952bcb59eSGnoCiYeH // 设置模式 190052bcb59eSGnoCiYeH ldata.icanon = termios.local_mode.contains(LocalMode::ICANON); 190152da9a59SGnoCiYeH 190252da9a59SGnoCiYeH // 设置回显 190352da9a59SGnoCiYeH if termios.local_mode.contains(LocalMode::ECHO) { 190452da9a59SGnoCiYeH ldata.echo = true; 190552da9a59SGnoCiYeH } 190652da9a59SGnoCiYeH 190752da9a59SGnoCiYeH if termios.input_mode.contains(InputMode::ISTRIP) 190852da9a59SGnoCiYeH || termios.input_mode.contains(InputMode::IUCLC) 190952da9a59SGnoCiYeH || termios.input_mode.contains(InputMode::IGNCR) 191052da9a59SGnoCiYeH || termios.input_mode.contains(InputMode::IXON) 191152da9a59SGnoCiYeH || termios.local_mode.contains(LocalMode::ISIG) 191252da9a59SGnoCiYeH || termios.local_mode.contains(LocalMode::ECHO) 191352da9a59SGnoCiYeH || termios.input_mode.contains(InputMode::PARMRK) 191452da9a59SGnoCiYeH { 191552da9a59SGnoCiYeH // 非原模式 191652da9a59SGnoCiYeH 191752da9a59SGnoCiYeH ldata.char_map.set_all(false); 191852da9a59SGnoCiYeH 191952da9a59SGnoCiYeH // 忽略回车符或者将回车映射为换行符 192052da9a59SGnoCiYeH if termios.input_mode.contains(InputMode::IGNCR) 192152da9a59SGnoCiYeH || termios.input_mode.contains(InputMode::ICRNL) 192252da9a59SGnoCiYeH { 192352da9a59SGnoCiYeH ldata.char_map.set('\r' as usize, true); 192452da9a59SGnoCiYeH } 192552da9a59SGnoCiYeH 192652da9a59SGnoCiYeH // 将换行映射为回车 192752da9a59SGnoCiYeH if termios.input_mode.contains(InputMode::INLCR) { 192852da9a59SGnoCiYeH ldata.char_map.set('\n' as usize, true); 192952da9a59SGnoCiYeH } 193052da9a59SGnoCiYeH 193152da9a59SGnoCiYeH // 规范模式 193252da9a59SGnoCiYeH if termios.local_mode.contains(LocalMode::ICANON) { 193352da9a59SGnoCiYeH ldata 193452da9a59SGnoCiYeH .char_map 193552da9a59SGnoCiYeH .set(contorl_chars[ControlCharIndex::VERASE] as usize, true); 193652da9a59SGnoCiYeH ldata 193752da9a59SGnoCiYeH .char_map 193852da9a59SGnoCiYeH .set(contorl_chars[ControlCharIndex::VKILL] as usize, true); 193952da9a59SGnoCiYeH ldata 194052da9a59SGnoCiYeH .char_map 194152da9a59SGnoCiYeH .set(contorl_chars[ControlCharIndex::VEOF] as usize, true); 194252da9a59SGnoCiYeH ldata.char_map.set('\n' as usize, true); 194352da9a59SGnoCiYeH ldata 194452da9a59SGnoCiYeH .char_map 194552da9a59SGnoCiYeH .set(contorl_chars[ControlCharIndex::VEOL] as usize, true); 194652da9a59SGnoCiYeH 194752da9a59SGnoCiYeH if termios.local_mode.contains(LocalMode::IEXTEN) { 194852da9a59SGnoCiYeH ldata 194952da9a59SGnoCiYeH .char_map 195052da9a59SGnoCiYeH .set(contorl_chars[ControlCharIndex::VWERASE] as usize, true); 195152da9a59SGnoCiYeH ldata 195252da9a59SGnoCiYeH .char_map 195352da9a59SGnoCiYeH .set(contorl_chars[ControlCharIndex::VLNEXT] as usize, true); 195452da9a59SGnoCiYeH ldata 195552da9a59SGnoCiYeH .char_map 195652da9a59SGnoCiYeH .set(contorl_chars[ControlCharIndex::VEOL2] as usize, true); 195752da9a59SGnoCiYeH if termios.local_mode.contains(LocalMode::ECHO) { 195852da9a59SGnoCiYeH ldata 195952da9a59SGnoCiYeH .char_map 196052da9a59SGnoCiYeH .set(contorl_chars[ControlCharIndex::VREPRINT] as usize, true); 196152da9a59SGnoCiYeH } 196252da9a59SGnoCiYeH } 196352da9a59SGnoCiYeH } 196452da9a59SGnoCiYeH 196552da9a59SGnoCiYeH // 软件流控制 196652da9a59SGnoCiYeH if termios.input_mode.contains(InputMode::IXON) { 196752da9a59SGnoCiYeH ldata 196852da9a59SGnoCiYeH .char_map 196952da9a59SGnoCiYeH .set(contorl_chars[ControlCharIndex::VSTART] as usize, true); 197052da9a59SGnoCiYeH ldata 197152da9a59SGnoCiYeH .char_map 197252da9a59SGnoCiYeH .set(contorl_chars[ControlCharIndex::VSTOP] as usize, true); 197352da9a59SGnoCiYeH } 197452da9a59SGnoCiYeH 197552da9a59SGnoCiYeH if termios.local_mode.contains(LocalMode::ISIG) { 197652da9a59SGnoCiYeH ldata 197752da9a59SGnoCiYeH .char_map 197852da9a59SGnoCiYeH .set(contorl_chars[ControlCharIndex::VINTR] as usize, true); 197952da9a59SGnoCiYeH ldata 198052da9a59SGnoCiYeH .char_map 198152da9a59SGnoCiYeH .set(contorl_chars[ControlCharIndex::VQUIT] as usize, true); 198252da9a59SGnoCiYeH ldata 198352da9a59SGnoCiYeH .char_map 198452da9a59SGnoCiYeH .set(contorl_chars[ControlCharIndex::VSUSP] as usize, true); 198552da9a59SGnoCiYeH } 198652da9a59SGnoCiYeH 198752da9a59SGnoCiYeH ldata 198852da9a59SGnoCiYeH .char_map 198952da9a59SGnoCiYeH .set(ControlCharIndex::DISABLE_CHAR as usize, true); 199052da9a59SGnoCiYeH ldata.raw = false; 199152da9a59SGnoCiYeH ldata.real_raw = false; 199252da9a59SGnoCiYeH } else { 199352da9a59SGnoCiYeH // 原模式或real_raw 199452da9a59SGnoCiYeH ldata.raw = true; 199552da9a59SGnoCiYeH 1996*b5b571e0SLoGin ldata.real_raw = termios.input_mode.contains(InputMode::IGNBRK) 199752da9a59SGnoCiYeH || (!termios.input_mode.contains(InputMode::BRKINT) 199852da9a59SGnoCiYeH && !termios.input_mode.contains(InputMode::PARMRK)) 199952da9a59SGnoCiYeH && (termios.input_mode.contains(InputMode::IGNPAR) 200052da9a59SGnoCiYeH || !termios.input_mode.contains(InputMode::INPCK)) 200152da9a59SGnoCiYeH && (core 200252da9a59SGnoCiYeH .driver() 200352da9a59SGnoCiYeH .flags() 2004*b5b571e0SLoGin .contains(TtyDriverFlag::TTY_DRIVER_REAL_RAW)); 200552da9a59SGnoCiYeH } 200652da9a59SGnoCiYeH 200752da9a59SGnoCiYeH // if !termios.input_mode.contains(InputMode::IXON) 200852da9a59SGnoCiYeH // && old.is_some() 200952da9a59SGnoCiYeH // && old.unwrap().input_mode.contains(InputMode::IXON) && ! 201052da9a59SGnoCiYeH // {} 201152da9a59SGnoCiYeH 201252da9a59SGnoCiYeH core.read_wq().wakeup_all(); 201352da9a59SGnoCiYeH core.write_wq().wakeup_all(); 201452da9a59SGnoCiYeH Ok(()) 201552da9a59SGnoCiYeH } 201652da9a59SGnoCiYeH 201752bcb59eSGnoCiYeH fn poll(&self, tty: Arc<TtyCore>) -> Result<usize, system_error::SystemError> { 201852bcb59eSGnoCiYeH let core = tty.core(); 201952bcb59eSGnoCiYeH let ldata = self.disc_data(); 202052bcb59eSGnoCiYeH 202152bcb59eSGnoCiYeH let mut event = EPollEventType::empty(); 202252bcb59eSGnoCiYeH if ldata.input_available(core.termios(), true) { 202352bcb59eSGnoCiYeH event.insert(EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM) 202452bcb59eSGnoCiYeH } 202552bcb59eSGnoCiYeH 202652bcb59eSGnoCiYeH if core.contorl_info_irqsave().packet { 202752bcb59eSGnoCiYeH let link = core.link(); 202852bcb59eSGnoCiYeH if link.is_some() && link.unwrap().core().contorl_info_irqsave().pktstatus != 0 { 202952bcb59eSGnoCiYeH event.insert( 203052bcb59eSGnoCiYeH EPollEventType::EPOLLPRI 203152bcb59eSGnoCiYeH | EPollEventType::EPOLLIN 203252bcb59eSGnoCiYeH | EPollEventType::EPOLLRDNORM, 203352bcb59eSGnoCiYeH ); 203452bcb59eSGnoCiYeH } 203552bcb59eSGnoCiYeH } 203652bcb59eSGnoCiYeH 203752bcb59eSGnoCiYeH if core.flags().contains(TtyFlag::OTHER_CLOSED) { 203852bcb59eSGnoCiYeH event.insert(EPollEventType::EPOLLHUP); 203952bcb59eSGnoCiYeH } 204052bcb59eSGnoCiYeH 204152bcb59eSGnoCiYeH if core.driver().driver_funcs().chars_in_buffer() < 256 204252bcb59eSGnoCiYeH && core.driver().driver_funcs().write_room(core) > 0 204352bcb59eSGnoCiYeH { 204452bcb59eSGnoCiYeH event.insert(EPollEventType::EPOLLOUT | EPollEventType::EPOLLWRNORM); 204552bcb59eSGnoCiYeH } 204652bcb59eSGnoCiYeH 204752bcb59eSGnoCiYeH Ok(event.bits() as usize) 204852da9a59SGnoCiYeH } 204952da9a59SGnoCiYeH 205052da9a59SGnoCiYeH fn hangup(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> { 205152da9a59SGnoCiYeH todo!() 205252da9a59SGnoCiYeH } 205352da9a59SGnoCiYeH 205452da9a59SGnoCiYeH fn receive_buf( 205552da9a59SGnoCiYeH &self, 205652da9a59SGnoCiYeH tty: Arc<TtyCore>, 205752da9a59SGnoCiYeH buf: &[u8], 205852da9a59SGnoCiYeH flags: Option<&[u8]>, 205952da9a59SGnoCiYeH count: usize, 206052da9a59SGnoCiYeH ) -> Result<usize, SystemError> { 206152da9a59SGnoCiYeH let mut ldata = self.disc_data(); 206252da9a59SGnoCiYeH ldata.receive_buf_common(tty, buf, flags, count, false) 206352da9a59SGnoCiYeH } 206452da9a59SGnoCiYeH 206552da9a59SGnoCiYeH fn receive_buf2( 206652da9a59SGnoCiYeH &self, 206752da9a59SGnoCiYeH tty: Arc<TtyCore>, 206852da9a59SGnoCiYeH buf: &[u8], 206952da9a59SGnoCiYeH flags: Option<&[u8]>, 207052da9a59SGnoCiYeH count: usize, 207152da9a59SGnoCiYeH ) -> Result<usize, SystemError> { 207252da9a59SGnoCiYeH let mut ldata = self.disc_data(); 207352da9a59SGnoCiYeH ldata.receive_buf_common(tty, buf, flags, count, true) 207452da9a59SGnoCiYeH } 207552da9a59SGnoCiYeH } 2076