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 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 1259365e801SGnoCiYeH tty: 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(), 1549365e801SGnoCiYeH tty: Weak::default(), 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 { 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 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; 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 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 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 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里的数据显示 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 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 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] 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: 读取尾 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 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: 一行已结束或者没有数据可读 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 /// ## 根据终端的模式和输入缓冲区中的数据量,判断是否可读字符 109152da9a59SGnoCiYeH 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: 无更多数据可读 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 终端驱动器标志之一,用于指定在写入终端设备之前对输出数据进行一些后期处理。 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 /// ## 处理回显 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)] 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() { 1347*bd70d2d1SLoGin 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() { 1360*bd70d2d1SLoGin 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 处理) 141452da9a59SGnoCiYeH 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输出一个字符 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 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 { 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 154952da9a59SGnoCiYeH fn close(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> { 155052da9a59SGnoCiYeH todo!() 155152da9a59SGnoCiYeH } 155252da9a59SGnoCiYeH 155352da9a59SGnoCiYeH /// ## 重置缓冲区的基本信息 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)] 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)] 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 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)] 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 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 209852da9a59SGnoCiYeH fn hangup(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> { 209952da9a59SGnoCiYeH todo!() 210052da9a59SGnoCiYeH } 210152da9a59SGnoCiYeH 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 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