xref: /DragonOS/kernel/src/driver/tty/tty_ldisc/ntty.rs (revision 52da9a59374752b4d01907b052135a0d317781dd)
1*52da9a59SGnoCiYeH use core::ops::BitXor;
2*52da9a59SGnoCiYeH 
3*52da9a59SGnoCiYeH use bitmap::{traits::BitMapOps, StaticBitmap};
4*52da9a59SGnoCiYeH 
5*52da9a59SGnoCiYeH use alloc::sync::{Arc, Weak};
6*52da9a59SGnoCiYeH use system_error::SystemError;
7*52da9a59SGnoCiYeH 
8*52da9a59SGnoCiYeH use crate::{
9*52da9a59SGnoCiYeH     arch::ipc::signal::Signal,
10*52da9a59SGnoCiYeH     driver::tty::{
11*52da9a59SGnoCiYeH         termios::{ControlCharIndex, InputMode, LocalMode, OutputMode, Termios},
12*52da9a59SGnoCiYeH         tty_core::{EchoOperation, TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd},
13*52da9a59SGnoCiYeH         tty_driver::{TtyDriverFlag, TtyOperation},
14*52da9a59SGnoCiYeH         tty_job_control::TtyJobCtrlManager,
15*52da9a59SGnoCiYeH     },
16*52da9a59SGnoCiYeH     filesystem::vfs::file::FileMode,
17*52da9a59SGnoCiYeH     libs::{
18*52da9a59SGnoCiYeH         rwlock::RwLockReadGuard,
19*52da9a59SGnoCiYeH         spinlock::{SpinLock, SpinLockGuard},
20*52da9a59SGnoCiYeH     },
21*52da9a59SGnoCiYeH     mm::VirtAddr,
22*52da9a59SGnoCiYeH     net::event_poll::EPollEventType,
23*52da9a59SGnoCiYeH     process::ProcessManager,
24*52da9a59SGnoCiYeH     syscall::{user_access::UserBufferWriter, Syscall},
25*52da9a59SGnoCiYeH };
26*52da9a59SGnoCiYeH 
27*52da9a59SGnoCiYeH use super::TtyLineDiscipline;
28*52da9a59SGnoCiYeH pub const NTTY_BUFSIZE: usize = 4096;
29*52da9a59SGnoCiYeH pub const ECHO_COMMIT_WATERMARK: usize = 256;
30*52da9a59SGnoCiYeH pub const ECHO_BLOCK: usize = 256;
31*52da9a59SGnoCiYeH pub const ECHO_DISCARD_WATERMARK: usize = NTTY_BUFSIZE - (ECHO_BLOCK + 32);
32*52da9a59SGnoCiYeH 
33*52da9a59SGnoCiYeH fn ntty_buf_mask(idx: usize) -> usize {
34*52da9a59SGnoCiYeH     return idx & (NTTY_BUFSIZE - 1);
35*52da9a59SGnoCiYeH }
36*52da9a59SGnoCiYeH 
37*52da9a59SGnoCiYeH #[derive(Debug)]
38*52da9a59SGnoCiYeH pub struct NTtyLinediscipline {
39*52da9a59SGnoCiYeH     pub data: SpinLock<NTtyData>,
40*52da9a59SGnoCiYeH }
41*52da9a59SGnoCiYeH 
42*52da9a59SGnoCiYeH impl NTtyLinediscipline {
43*52da9a59SGnoCiYeH     #[inline]
44*52da9a59SGnoCiYeH     pub fn disc_data(&self) -> SpinLockGuard<NTtyData> {
45*52da9a59SGnoCiYeH         self.data.lock_irqsave()
46*52da9a59SGnoCiYeH     }
47*52da9a59SGnoCiYeH 
48*52da9a59SGnoCiYeH     #[inline]
49*52da9a59SGnoCiYeH     pub fn disc_data_try_lock(&self) -> Result<SpinLockGuard<NTtyData>, SystemError> {
50*52da9a59SGnoCiYeH         self.data.try_lock_irqsave()
51*52da9a59SGnoCiYeH     }
52*52da9a59SGnoCiYeH 
53*52da9a59SGnoCiYeH     fn ioctl_helper(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> {
54*52da9a59SGnoCiYeH         match cmd {
55*52da9a59SGnoCiYeH             TtyIoctlCmd::TCXONC => {
56*52da9a59SGnoCiYeH                 todo!()
57*52da9a59SGnoCiYeH             }
58*52da9a59SGnoCiYeH             TtyIoctlCmd::TCFLSH => {
59*52da9a59SGnoCiYeH                 todo!()
60*52da9a59SGnoCiYeH             }
61*52da9a59SGnoCiYeH             _ => {
62*52da9a59SGnoCiYeH                 return tty.tty_mode_ioctl(tty.clone(), cmd, arg);
63*52da9a59SGnoCiYeH             }
64*52da9a59SGnoCiYeH         }
65*52da9a59SGnoCiYeH     }
66*52da9a59SGnoCiYeH }
67*52da9a59SGnoCiYeH 
68*52da9a59SGnoCiYeH #[derive(Debug)]
69*52da9a59SGnoCiYeH pub struct NTtyData {
70*52da9a59SGnoCiYeH     /// 写者管理,tty只有一个写者,即ttydevice,所以不需要加锁
71*52da9a59SGnoCiYeH     /// 读取缓冲区的头指针,表示下一个将要接受进buf的字符的位置
72*52da9a59SGnoCiYeH     read_head: usize,
73*52da9a59SGnoCiYeH     ///  提交缓冲区的头指针,用于行规程处理
74*52da9a59SGnoCiYeH     commit_head: usize,
75*52da9a59SGnoCiYeH     /// 规范缓冲区的头指针,用于规范模式的处理
76*52da9a59SGnoCiYeH     canon_head: usize,
77*52da9a59SGnoCiYeH     /// 回显缓冲区的头指针,用于存储需要回显的字符
78*52da9a59SGnoCiYeH     echo_head: usize,
79*52da9a59SGnoCiYeH     /// 回显过程中用于提交的头指针
80*52da9a59SGnoCiYeH     echo_commit: usize,
81*52da9a59SGnoCiYeH     /// 标记回显字符的起始位置
82*52da9a59SGnoCiYeH     echo_mark: usize,
83*52da9a59SGnoCiYeH 
84*52da9a59SGnoCiYeH     /// 读者管理
85*52da9a59SGnoCiYeH     /// 读取字符的尾指针,即当前读取位置
86*52da9a59SGnoCiYeH     read_tail: usize,
87*52da9a59SGnoCiYeH     /// 行的起始位置
88*52da9a59SGnoCiYeH     line_start: usize,
89*52da9a59SGnoCiYeH     /// 预读字符数,用于处理控制字符
90*52da9a59SGnoCiYeH     lookahead_count: usize,
91*52da9a59SGnoCiYeH 
92*52da9a59SGnoCiYeH     // 更改以下六个标记时必须持有termios的锁
93*52da9a59SGnoCiYeH     /// Line-next 标志,表示下一个输入字符应当按字面处理
94*52da9a59SGnoCiYeH     lnext: bool,
95*52da9a59SGnoCiYeH     /// 擦除状态的标志
96*52da9a59SGnoCiYeH     erasing: bool,
97*52da9a59SGnoCiYeH     /// Raw 模式的标志
98*52da9a59SGnoCiYeH     raw: bool,
99*52da9a59SGnoCiYeH     /// Real raw 模式的标志
100*52da9a59SGnoCiYeH     real_raw: bool,
101*52da9a59SGnoCiYeH     /// 规范模式的标志
102*52da9a59SGnoCiYeH     icanon: bool,
103*52da9a59SGnoCiYeH     /// 是否开启echo
104*52da9a59SGnoCiYeH     echo: bool,
105*52da9a59SGnoCiYeH     ///  标志是否正在进行推送
106*52da9a59SGnoCiYeH     pushing: bool,
107*52da9a59SGnoCiYeH     /// 是否没有空间可写
108*52da9a59SGnoCiYeH     no_room: bool,
109*52da9a59SGnoCiYeH 
110*52da9a59SGnoCiYeH     /// 光标所在列
111*52da9a59SGnoCiYeH     cursor_column: u32,
112*52da9a59SGnoCiYeH     /// 规范模式下光标所在列
113*52da9a59SGnoCiYeH     canon_cursor_column: u32,
114*52da9a59SGnoCiYeH     /// 回显缓冲区的尾指针
115*52da9a59SGnoCiYeH     echo_tail: usize,
116*52da9a59SGnoCiYeH 
117*52da9a59SGnoCiYeH     /// 写者与读者共享
118*52da9a59SGnoCiYeH     read_buf: [u8; NTTY_BUFSIZE],
119*52da9a59SGnoCiYeH     echo_buf: [u8; NTTY_BUFSIZE],
120*52da9a59SGnoCiYeH 
121*52da9a59SGnoCiYeH     read_flags: StaticBitmap<NTTY_BUFSIZE>,
122*52da9a59SGnoCiYeH     char_map: StaticBitmap<256>,
123*52da9a59SGnoCiYeH 
124*52da9a59SGnoCiYeH     tty: Option<Weak<TtyCore>>,
125*52da9a59SGnoCiYeH }
126*52da9a59SGnoCiYeH 
127*52da9a59SGnoCiYeH impl NTtyData {
128*52da9a59SGnoCiYeH     pub fn new() -> Self {
129*52da9a59SGnoCiYeH         Self {
130*52da9a59SGnoCiYeH             read_head: 0,
131*52da9a59SGnoCiYeH             commit_head: 0,
132*52da9a59SGnoCiYeH             canon_head: 0,
133*52da9a59SGnoCiYeH             echo_head: 0,
134*52da9a59SGnoCiYeH             echo_commit: 0,
135*52da9a59SGnoCiYeH             echo_mark: 0,
136*52da9a59SGnoCiYeH             read_tail: 0,
137*52da9a59SGnoCiYeH             line_start: 0,
138*52da9a59SGnoCiYeH             lookahead_count: 0,
139*52da9a59SGnoCiYeH             lnext: false,
140*52da9a59SGnoCiYeH             erasing: false,
141*52da9a59SGnoCiYeH             raw: false,
142*52da9a59SGnoCiYeH             real_raw: false,
143*52da9a59SGnoCiYeH             icanon: false,
144*52da9a59SGnoCiYeH             pushing: false,
145*52da9a59SGnoCiYeH             echo: false,
146*52da9a59SGnoCiYeH             cursor_column: 0,
147*52da9a59SGnoCiYeH             canon_cursor_column: 0,
148*52da9a59SGnoCiYeH             echo_tail: 0,
149*52da9a59SGnoCiYeH             read_buf: [0; NTTY_BUFSIZE],
150*52da9a59SGnoCiYeH             echo_buf: [0; NTTY_BUFSIZE],
151*52da9a59SGnoCiYeH             read_flags: StaticBitmap::new(),
152*52da9a59SGnoCiYeH             char_map: StaticBitmap::new(),
153*52da9a59SGnoCiYeH             tty: None,
154*52da9a59SGnoCiYeH             no_room: false,
155*52da9a59SGnoCiYeH         }
156*52da9a59SGnoCiYeH     }
157*52da9a59SGnoCiYeH 
158*52da9a59SGnoCiYeH     #[inline]
159*52da9a59SGnoCiYeH     pub fn read_cnt(&self) -> usize {
160*52da9a59SGnoCiYeH         self.read_head - self.read_tail
161*52da9a59SGnoCiYeH     }
162*52da9a59SGnoCiYeH 
163*52da9a59SGnoCiYeH     #[inline]
164*52da9a59SGnoCiYeH     pub fn read_at(&self, i: usize) -> u8 {
165*52da9a59SGnoCiYeH         let i = i & (NTTY_BUFSIZE - 1);
166*52da9a59SGnoCiYeH         self.read_buf[i]
167*52da9a59SGnoCiYeH     }
168*52da9a59SGnoCiYeH 
169*52da9a59SGnoCiYeH     /// ### 接收数据到NTTY
170*52da9a59SGnoCiYeH     pub fn receive_buf_common(
171*52da9a59SGnoCiYeH         &mut self,
172*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
173*52da9a59SGnoCiYeH         buf: &[u8],
174*52da9a59SGnoCiYeH         flags: Option<&[u8]>,
175*52da9a59SGnoCiYeH         mut count: usize,
176*52da9a59SGnoCiYeH         flow: bool,
177*52da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
178*52da9a59SGnoCiYeH         // 获取termios读锁
179*52da9a59SGnoCiYeH         let termios = tty.core().termios();
180*52da9a59SGnoCiYeH         let mut overflow;
181*52da9a59SGnoCiYeH         let mut n;
182*52da9a59SGnoCiYeH         let mut offset = 0;
183*52da9a59SGnoCiYeH         let mut recved = 0;
184*52da9a59SGnoCiYeH         loop {
185*52da9a59SGnoCiYeH             let tail = self.read_tail;
186*52da9a59SGnoCiYeH 
187*52da9a59SGnoCiYeH             let mut room = NTTY_BUFSIZE - (self.read_head - tail);
188*52da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::PARMRK) {
189*52da9a59SGnoCiYeH                 room = (room + 2) / 3;
190*52da9a59SGnoCiYeH             }
191*52da9a59SGnoCiYeH 
192*52da9a59SGnoCiYeH             room -= 1;
193*52da9a59SGnoCiYeH             if room == 0 || room > NTTY_BUFSIZE {
194*52da9a59SGnoCiYeH                 // 可能溢出
195*52da9a59SGnoCiYeH                 overflow = self.icanon && self.canon_head == tail;
196*52da9a59SGnoCiYeH                 if room > NTTY_BUFSIZE && overflow {
197*52da9a59SGnoCiYeH                     self.read_head -= 1;
198*52da9a59SGnoCiYeH                 }
199*52da9a59SGnoCiYeH                 self.no_room = flow && !overflow;
200*52da9a59SGnoCiYeH                 room = if overflow { !0 } else { 0 }
201*52da9a59SGnoCiYeH             } else {
202*52da9a59SGnoCiYeH                 overflow = false;
203*52da9a59SGnoCiYeH             }
204*52da9a59SGnoCiYeH 
205*52da9a59SGnoCiYeH             n = count.min(room);
206*52da9a59SGnoCiYeH             if n == 0 {
207*52da9a59SGnoCiYeH                 break;
208*52da9a59SGnoCiYeH             }
209*52da9a59SGnoCiYeH 
210*52da9a59SGnoCiYeH             if !overflow {
211*52da9a59SGnoCiYeH                 if flags.is_none() {
212*52da9a59SGnoCiYeH                     self.receive_buf(tty.clone(), &buf[offset..], flags, n);
213*52da9a59SGnoCiYeH                 } else {
214*52da9a59SGnoCiYeH                     self.receive_buf(
215*52da9a59SGnoCiYeH                         tty.clone(),
216*52da9a59SGnoCiYeH                         &buf[offset..],
217*52da9a59SGnoCiYeH                         Some(&flags.unwrap()[offset..]),
218*52da9a59SGnoCiYeH                         n,
219*52da9a59SGnoCiYeH                     );
220*52da9a59SGnoCiYeH                 }
221*52da9a59SGnoCiYeH             }
222*52da9a59SGnoCiYeH 
223*52da9a59SGnoCiYeH             offset += n;
224*52da9a59SGnoCiYeH 
225*52da9a59SGnoCiYeH             count -= n;
226*52da9a59SGnoCiYeH 
227*52da9a59SGnoCiYeH             recved += n;
228*52da9a59SGnoCiYeH 
229*52da9a59SGnoCiYeH             if tty.core().flags().contains(TtyFlag::LDISC_CHANGING) {
230*52da9a59SGnoCiYeH                 break;
231*52da9a59SGnoCiYeH             }
232*52da9a59SGnoCiYeH         }
233*52da9a59SGnoCiYeH 
234*52da9a59SGnoCiYeH         // TODO: throttle
235*52da9a59SGnoCiYeH 
236*52da9a59SGnoCiYeH         Ok(recved)
237*52da9a59SGnoCiYeH     }
238*52da9a59SGnoCiYeH 
239*52da9a59SGnoCiYeH     pub fn receive_buf(
240*52da9a59SGnoCiYeH         &mut self,
241*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
242*52da9a59SGnoCiYeH         buf: &[u8],
243*52da9a59SGnoCiYeH         flags: Option<&[u8]>,
244*52da9a59SGnoCiYeH         count: usize,
245*52da9a59SGnoCiYeH     ) {
246*52da9a59SGnoCiYeH         let termios = tty.core().termios();
247*52da9a59SGnoCiYeH         let preops = termios.input_mode.contains(InputMode::ISTRIP)
248*52da9a59SGnoCiYeH             || termios.input_mode.contains(InputMode::IUCLC)
249*52da9a59SGnoCiYeH             || termios.local_mode.contains(LocalMode::IEXTEN);
250*52da9a59SGnoCiYeH 
251*52da9a59SGnoCiYeH         let look_ahead = self.lookahead_count.min(count);
252*52da9a59SGnoCiYeH 
253*52da9a59SGnoCiYeH         if self.real_raw {
254*52da9a59SGnoCiYeH             todo!("tty real raw mode todo");
255*52da9a59SGnoCiYeH         } else if self.raw || (termios.local_mode.contains(LocalMode::EXTPROC) && !preops) {
256*52da9a59SGnoCiYeH             todo!("tty raw mode todo");
257*52da9a59SGnoCiYeH         } else if tty.core().is_closing() && !termios.local_mode.contains(LocalMode::EXTPROC) {
258*52da9a59SGnoCiYeH             todo!()
259*52da9a59SGnoCiYeH         } else {
260*52da9a59SGnoCiYeH             if look_ahead > 0 {
261*52da9a59SGnoCiYeH                 self.receive_buf_standard(tty.clone(), buf, flags, look_ahead, true);
262*52da9a59SGnoCiYeH             }
263*52da9a59SGnoCiYeH 
264*52da9a59SGnoCiYeH             if count > look_ahead {
265*52da9a59SGnoCiYeH                 self.receive_buf_standard(tty.clone(), buf, flags, count - look_ahead, false);
266*52da9a59SGnoCiYeH             }
267*52da9a59SGnoCiYeH 
268*52da9a59SGnoCiYeH             // 刷新echo
269*52da9a59SGnoCiYeH             self.flush_echoes(tty.clone());
270*52da9a59SGnoCiYeH 
271*52da9a59SGnoCiYeH             tty.flush_chars(tty.core());
272*52da9a59SGnoCiYeH         }
273*52da9a59SGnoCiYeH 
274*52da9a59SGnoCiYeH         self.lookahead_count -= look_ahead;
275*52da9a59SGnoCiYeH 
276*52da9a59SGnoCiYeH         if self.icanon && !termios.local_mode.contains(LocalMode::EXTPROC) {
277*52da9a59SGnoCiYeH             return;
278*52da9a59SGnoCiYeH         }
279*52da9a59SGnoCiYeH 
280*52da9a59SGnoCiYeH         self.commit_head = self.read_head;
281*52da9a59SGnoCiYeH 
282*52da9a59SGnoCiYeH         if self.read_cnt() > 0 {
283*52da9a59SGnoCiYeH             tty.core()
284*52da9a59SGnoCiYeH                 .read_wq()
285*52da9a59SGnoCiYeH                 .wakeup((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDBAND).bits() as u64);
286*52da9a59SGnoCiYeH         }
287*52da9a59SGnoCiYeH     }
288*52da9a59SGnoCiYeH 
289*52da9a59SGnoCiYeH     pub fn flush_echoes(&mut self, tty: Arc<TtyCore>) {
290*52da9a59SGnoCiYeH         let termios = tty.core().termios();
291*52da9a59SGnoCiYeH         if !termios.local_mode.contains(LocalMode::ECHO)
292*52da9a59SGnoCiYeH             && !termios.local_mode.contains(LocalMode::ECHONL)
293*52da9a59SGnoCiYeH             || self.echo_commit == self.echo_head
294*52da9a59SGnoCiYeH         {
295*52da9a59SGnoCiYeH             return;
296*52da9a59SGnoCiYeH         }
297*52da9a59SGnoCiYeH 
298*52da9a59SGnoCiYeH         self.echo_commit = self.echo_head;
299*52da9a59SGnoCiYeH         drop(termios);
300*52da9a59SGnoCiYeH         let _ = self.echoes(tty);
301*52da9a59SGnoCiYeH     }
302*52da9a59SGnoCiYeH 
303*52da9a59SGnoCiYeH     pub fn receive_buf_standard(
304*52da9a59SGnoCiYeH         &mut self,
305*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
306*52da9a59SGnoCiYeH         buf: &[u8],
307*52da9a59SGnoCiYeH         flags: Option<&[u8]>,
308*52da9a59SGnoCiYeH         mut count: usize,
309*52da9a59SGnoCiYeH         lookahead_done: bool,
310*52da9a59SGnoCiYeH     ) {
311*52da9a59SGnoCiYeH         let termios = tty.core().termios();
312*52da9a59SGnoCiYeH         if flags.is_some() {
313*52da9a59SGnoCiYeH             todo!("ntty recv buf flags todo");
314*52da9a59SGnoCiYeH         }
315*52da9a59SGnoCiYeH 
316*52da9a59SGnoCiYeH         let mut offset = 0;
317*52da9a59SGnoCiYeH         while count > 0 {
318*52da9a59SGnoCiYeH             if offset >= buf.len() {
319*52da9a59SGnoCiYeH                 break;
320*52da9a59SGnoCiYeH             }
321*52da9a59SGnoCiYeH             let mut c = buf[offset];
322*52da9a59SGnoCiYeH             offset += 1;
323*52da9a59SGnoCiYeH 
324*52da9a59SGnoCiYeH             if self.lnext {
325*52da9a59SGnoCiYeH                 // 将下一个字符当做字面值处理
326*52da9a59SGnoCiYeH                 self.lnext = false;
327*52da9a59SGnoCiYeH                 if termios.input_mode.contains(InputMode::ISTRIP) {
328*52da9a59SGnoCiYeH                     c &= 0x7f;
329*52da9a59SGnoCiYeH                 }
330*52da9a59SGnoCiYeH 
331*52da9a59SGnoCiYeH                 if termios.input_mode.contains(InputMode::IUCLC)
332*52da9a59SGnoCiYeH                     && termios.local_mode.contains(LocalMode::IEXTEN)
333*52da9a59SGnoCiYeH                 {
334*52da9a59SGnoCiYeH                     c = (c as char).to_ascii_lowercase() as u8;
335*52da9a59SGnoCiYeH                     self.receive_char(c, tty.clone())
336*52da9a59SGnoCiYeH                 }
337*52da9a59SGnoCiYeH 
338*52da9a59SGnoCiYeH                 continue;
339*52da9a59SGnoCiYeH             }
340*52da9a59SGnoCiYeH 
341*52da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::ISTRIP) {
342*52da9a59SGnoCiYeH                 c &= 0x7f;
343*52da9a59SGnoCiYeH             }
344*52da9a59SGnoCiYeH 
345*52da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::IUCLC)
346*52da9a59SGnoCiYeH                 && termios.local_mode.contains(LocalMode::IEXTEN)
347*52da9a59SGnoCiYeH             {
348*52da9a59SGnoCiYeH                 c = (c as char).to_ascii_lowercase() as u8;
349*52da9a59SGnoCiYeH             }
350*52da9a59SGnoCiYeH 
351*52da9a59SGnoCiYeH             if termios.local_mode.contains(LocalMode::EXTPROC) {
352*52da9a59SGnoCiYeH                 self.add_read_byte(c);
353*52da9a59SGnoCiYeH                 continue;
354*52da9a59SGnoCiYeH             }
355*52da9a59SGnoCiYeH 
356*52da9a59SGnoCiYeH             if self.char_map.get(c as usize).unwrap() {
357*52da9a59SGnoCiYeH                 // 特殊字符
358*52da9a59SGnoCiYeH                 self.receive_special_char(c, tty.clone(), lookahead_done)
359*52da9a59SGnoCiYeH             } else {
360*52da9a59SGnoCiYeH                 self.receive_char(c, tty.clone());
361*52da9a59SGnoCiYeH             }
362*52da9a59SGnoCiYeH 
363*52da9a59SGnoCiYeH             count -= 1;
364*52da9a59SGnoCiYeH         }
365*52da9a59SGnoCiYeH     }
366*52da9a59SGnoCiYeH 
367*52da9a59SGnoCiYeH     pub fn receive_special_char(&mut self, mut c: u8, tty: Arc<TtyCore>, lookahead_done: bool) {
368*52da9a59SGnoCiYeH         let is_flow_ctrl = self.is_flow_ctrl_char(tty.clone(), c, lookahead_done);
369*52da9a59SGnoCiYeH         let termios = tty.core().termios();
370*52da9a59SGnoCiYeH 
371*52da9a59SGnoCiYeH         // 启用软件流控,并且该字符已经当做软件流控字符处理
372*52da9a59SGnoCiYeH         if termios.input_mode.contains(InputMode::IXON) && is_flow_ctrl {
373*52da9a59SGnoCiYeH             return;
374*52da9a59SGnoCiYeH         }
375*52da9a59SGnoCiYeH 
376*52da9a59SGnoCiYeH         if termios.local_mode.contains(LocalMode::ISIG) {
377*52da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VINTR] {
378*52da9a59SGnoCiYeH                 self.recv_sig_char(tty.clone(), &termios, Signal::SIGINT, c);
379*52da9a59SGnoCiYeH                 return;
380*52da9a59SGnoCiYeH             }
381*52da9a59SGnoCiYeH 
382*52da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VQUIT] {
383*52da9a59SGnoCiYeH                 self.recv_sig_char(tty.clone(), &termios, Signal::SIGQUIT, c);
384*52da9a59SGnoCiYeH                 return;
385*52da9a59SGnoCiYeH             }
386*52da9a59SGnoCiYeH 
387*52da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VSUSP] {
388*52da9a59SGnoCiYeH                 self.recv_sig_char(tty.clone(), &termios, Signal::SIGTSTP, c);
389*52da9a59SGnoCiYeH                 return;
390*52da9a59SGnoCiYeH             }
391*52da9a59SGnoCiYeH         }
392*52da9a59SGnoCiYeH 
393*52da9a59SGnoCiYeH         let flow = tty.core().flow_irqsave();
394*52da9a59SGnoCiYeH         if flow.stopped
395*52da9a59SGnoCiYeH             && !flow.tco_stopped
396*52da9a59SGnoCiYeH             && termios.input_mode.contains(InputMode::IXON)
397*52da9a59SGnoCiYeH             && termios.input_mode.contains(InputMode::IXANY)
398*52da9a59SGnoCiYeH         {
399*52da9a59SGnoCiYeH             tty.tty_start();
400*52da9a59SGnoCiYeH             self.process_echoes(tty.clone());
401*52da9a59SGnoCiYeH         }
402*52da9a59SGnoCiYeH         drop(flow);
403*52da9a59SGnoCiYeH 
404*52da9a59SGnoCiYeH         if c == b'\r' {
405*52da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::IGNCR) {
406*52da9a59SGnoCiYeH                 // 忽略
407*52da9a59SGnoCiYeH                 return;
408*52da9a59SGnoCiYeH             }
409*52da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::ICRNL) {
410*52da9a59SGnoCiYeH                 // 映射为换行
411*52da9a59SGnoCiYeH                 c = b'\n';
412*52da9a59SGnoCiYeH             }
413*52da9a59SGnoCiYeH         } else if c == b'\n' && termios.input_mode.contains(InputMode::INLCR) {
414*52da9a59SGnoCiYeH             // 映射为回车
415*52da9a59SGnoCiYeH             c = b'\r';
416*52da9a59SGnoCiYeH         }
417*52da9a59SGnoCiYeH 
418*52da9a59SGnoCiYeH         if self.icanon {
419*52da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VERASE]
420*52da9a59SGnoCiYeH                 || c == termios.control_characters[ControlCharIndex::VKILL]
421*52da9a59SGnoCiYeH                 || (c == termios.control_characters[ControlCharIndex::VWERASE]
422*52da9a59SGnoCiYeH                     && termios.local_mode.contains(LocalMode::IEXTEN))
423*52da9a59SGnoCiYeH             {
424*52da9a59SGnoCiYeH                 self.eraser(c, &termios);
425*52da9a59SGnoCiYeH                 self.commit_echoes(tty.clone());
426*52da9a59SGnoCiYeH                 return;
427*52da9a59SGnoCiYeH             }
428*52da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VLNEXT]
429*52da9a59SGnoCiYeH                 && termios.local_mode.contains(LocalMode::IEXTEN)
430*52da9a59SGnoCiYeH             {
431*52da9a59SGnoCiYeH                 self.lnext = true;
432*52da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::ECHO) {
433*52da9a59SGnoCiYeH                     self.finish_erasing();
434*52da9a59SGnoCiYeH                     if termios.local_mode.contains(LocalMode::ECHOCTL) {
435*52da9a59SGnoCiYeH                         self.echo_char_raw(b'^');
436*52da9a59SGnoCiYeH                         self.echo_char_raw(8);
437*52da9a59SGnoCiYeH                         self.commit_echoes(tty.clone());
438*52da9a59SGnoCiYeH                     }
439*52da9a59SGnoCiYeH                 }
440*52da9a59SGnoCiYeH                 return;
441*52da9a59SGnoCiYeH             }
442*52da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VREPRINT]
443*52da9a59SGnoCiYeH                 && termios.local_mode.contains(LocalMode::ECHO)
444*52da9a59SGnoCiYeH                 && termios.local_mode.contains(LocalMode::IEXTEN)
445*52da9a59SGnoCiYeH             {
446*52da9a59SGnoCiYeH                 let mut tail = self.canon_head;
447*52da9a59SGnoCiYeH                 self.finish_erasing();
448*52da9a59SGnoCiYeH                 self.echo_char(c, &termios);
449*52da9a59SGnoCiYeH                 self.echo_char_raw(b'\n');
450*52da9a59SGnoCiYeH                 while ntty_buf_mask(tail) != ntty_buf_mask(self.read_head) {
451*52da9a59SGnoCiYeH                     self.echo_char(self.read_buf[ntty_buf_mask(tail)], &termios);
452*52da9a59SGnoCiYeH                     tail += 1;
453*52da9a59SGnoCiYeH                 }
454*52da9a59SGnoCiYeH                 self.commit_echoes(tty.clone());
455*52da9a59SGnoCiYeH                 return;
456*52da9a59SGnoCiYeH             }
457*52da9a59SGnoCiYeH 
458*52da9a59SGnoCiYeH             if c == b'\n' {
459*52da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::ECHO)
460*52da9a59SGnoCiYeH                     || termios.local_mode.contains(LocalMode::ECHONL)
461*52da9a59SGnoCiYeH                 {
462*52da9a59SGnoCiYeH                     self.echo_char_raw(b'\n');
463*52da9a59SGnoCiYeH                     self.commit_echoes(tty.clone());
464*52da9a59SGnoCiYeH                 }
465*52da9a59SGnoCiYeH 
466*52da9a59SGnoCiYeH                 self.read_flags.set(ntty_buf_mask(self.read_head), true);
467*52da9a59SGnoCiYeH                 self.read_buf[ntty_buf_mask(self.read_head)] = c;
468*52da9a59SGnoCiYeH                 self.read_head += 1;
469*52da9a59SGnoCiYeH                 self.canon_head = self.read_head;
470*52da9a59SGnoCiYeH                 tty.core()
471*52da9a59SGnoCiYeH                     .read_wq()
472*52da9a59SGnoCiYeH                     .wakeup((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64);
473*52da9a59SGnoCiYeH                 return;
474*52da9a59SGnoCiYeH             }
475*52da9a59SGnoCiYeH 
476*52da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VEOF] {
477*52da9a59SGnoCiYeH                 c = ControlCharIndex::DISABLE_CHAR;
478*52da9a59SGnoCiYeH 
479*52da9a59SGnoCiYeH                 self.read_flags.set(ntty_buf_mask(self.read_head), true);
480*52da9a59SGnoCiYeH                 self.read_buf[ntty_buf_mask(self.read_head)] = c;
481*52da9a59SGnoCiYeH                 self.read_head += 1;
482*52da9a59SGnoCiYeH                 self.canon_head = self.read_head;
483*52da9a59SGnoCiYeH                 tty.core()
484*52da9a59SGnoCiYeH                     .read_wq()
485*52da9a59SGnoCiYeH                     .wakeup((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64);
486*52da9a59SGnoCiYeH                 return;
487*52da9a59SGnoCiYeH             }
488*52da9a59SGnoCiYeH 
489*52da9a59SGnoCiYeH             if c == termios.control_characters[ControlCharIndex::VEOL]
490*52da9a59SGnoCiYeH                 || (c == termios.control_characters[ControlCharIndex::VEOL2]
491*52da9a59SGnoCiYeH                     && termios.local_mode.contains(LocalMode::IEXTEN))
492*52da9a59SGnoCiYeH             {
493*52da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::ECHO) {
494*52da9a59SGnoCiYeH                     if self.canon_head == self.read_head {
495*52da9a59SGnoCiYeH                         self.add_echo_byte(EchoOperation::Start.to_u8());
496*52da9a59SGnoCiYeH                         self.add_echo_byte(EchoOperation::SetCanonCol.to_u8());
497*52da9a59SGnoCiYeH                     }
498*52da9a59SGnoCiYeH                     self.echo_char(c, &termios);
499*52da9a59SGnoCiYeH                     self.commit_echoes(tty.clone());
500*52da9a59SGnoCiYeH                 }
501*52da9a59SGnoCiYeH 
502*52da9a59SGnoCiYeH                 if c == 0o377 && termios.input_mode.contains(InputMode::PARMRK) {
503*52da9a59SGnoCiYeH                     self.read_buf[ntty_buf_mask(self.read_head)] = c;
504*52da9a59SGnoCiYeH                     self.read_head += 1;
505*52da9a59SGnoCiYeH                 }
506*52da9a59SGnoCiYeH 
507*52da9a59SGnoCiYeH                 self.read_flags.set(ntty_buf_mask(self.read_head), true);
508*52da9a59SGnoCiYeH                 self.read_buf[ntty_buf_mask(self.read_head)] = c;
509*52da9a59SGnoCiYeH                 self.read_head += 1;
510*52da9a59SGnoCiYeH                 self.canon_head = self.read_head;
511*52da9a59SGnoCiYeH                 tty.core()
512*52da9a59SGnoCiYeH                     .read_wq()
513*52da9a59SGnoCiYeH                     .wakeup((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64);
514*52da9a59SGnoCiYeH                 return;
515*52da9a59SGnoCiYeH             }
516*52da9a59SGnoCiYeH         }
517*52da9a59SGnoCiYeH 
518*52da9a59SGnoCiYeH         if termios.local_mode.contains(LocalMode::ECHO) {
519*52da9a59SGnoCiYeH             self.finish_erasing();
520*52da9a59SGnoCiYeH             if c == b'\n' {
521*52da9a59SGnoCiYeH                 self.echo_char_raw(b'\n');
522*52da9a59SGnoCiYeH             } else {
523*52da9a59SGnoCiYeH                 if self.canon_head == self.read_head {
524*52da9a59SGnoCiYeH                     self.add_echo_byte(EchoOperation::Start.to_u8());
525*52da9a59SGnoCiYeH                     self.add_echo_byte(EchoOperation::SetCanonCol.to_u8());
526*52da9a59SGnoCiYeH                 }
527*52da9a59SGnoCiYeH                 self.echo_char(c, &termios);
528*52da9a59SGnoCiYeH             }
529*52da9a59SGnoCiYeH 
530*52da9a59SGnoCiYeH             self.commit_echoes(tty.clone());
531*52da9a59SGnoCiYeH         }
532*52da9a59SGnoCiYeH 
533*52da9a59SGnoCiYeH         if c == 0o377 && termios.input_mode.contains(InputMode::PARMRK) {
534*52da9a59SGnoCiYeH             self.read_buf[ntty_buf_mask(self.read_head)] = c;
535*52da9a59SGnoCiYeH             self.read_head += 1;
536*52da9a59SGnoCiYeH         }
537*52da9a59SGnoCiYeH 
538*52da9a59SGnoCiYeH         self.read_buf[ntty_buf_mask(self.read_head)] = c;
539*52da9a59SGnoCiYeH         self.read_head += 1;
540*52da9a59SGnoCiYeH     }
541*52da9a59SGnoCiYeH 
542*52da9a59SGnoCiYeH     /// ## ntty默认eraser function
543*52da9a59SGnoCiYeH     fn eraser(&mut self, mut c: u8, termios: &RwLockReadGuard<Termios>) {
544*52da9a59SGnoCiYeH         if self.read_head == self.canon_head {
545*52da9a59SGnoCiYeH             return;
546*52da9a59SGnoCiYeH         }
547*52da9a59SGnoCiYeH 
548*52da9a59SGnoCiYeH         let erase = c == termios.control_characters[ControlCharIndex::VERASE];
549*52da9a59SGnoCiYeH         let werase = c == termios.control_characters[ControlCharIndex::VWERASE];
550*52da9a59SGnoCiYeH         let kill = !erase && !werase;
551*52da9a59SGnoCiYeH 
552*52da9a59SGnoCiYeH         if kill {
553*52da9a59SGnoCiYeH             if !termios.local_mode.contains(LocalMode::ECHO) {
554*52da9a59SGnoCiYeH                 self.read_head = self.canon_head;
555*52da9a59SGnoCiYeH                 return;
556*52da9a59SGnoCiYeH             }
557*52da9a59SGnoCiYeH             if !termios.local_mode.contains(LocalMode::ECHOK)
558*52da9a59SGnoCiYeH                 || !termios.local_mode.contains(LocalMode::ECHOKE)
559*52da9a59SGnoCiYeH                 || !termios.local_mode.contains(LocalMode::ECHOE)
560*52da9a59SGnoCiYeH             {
561*52da9a59SGnoCiYeH                 self.read_head = self.canon_head;
562*52da9a59SGnoCiYeH                 if self.erasing {
563*52da9a59SGnoCiYeH                     self.echo_char_raw(c);
564*52da9a59SGnoCiYeH                     self.erasing = false;
565*52da9a59SGnoCiYeH                 }
566*52da9a59SGnoCiYeH                 self.echo_char(c, termios);
567*52da9a59SGnoCiYeH 
568*52da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::ECHOK) {
569*52da9a59SGnoCiYeH                     // 添加新行
570*52da9a59SGnoCiYeH                     self.echo_char_raw(b'\n');
571*52da9a59SGnoCiYeH                 }
572*52da9a59SGnoCiYeH                 return;
573*52da9a59SGnoCiYeH             }
574*52da9a59SGnoCiYeH         }
575*52da9a59SGnoCiYeH 
576*52da9a59SGnoCiYeH         let mut head;
577*52da9a59SGnoCiYeH         let mut cnt;
578*52da9a59SGnoCiYeH         while ntty_buf_mask(self.read_head) != ntty_buf_mask(self.canon_head) {
579*52da9a59SGnoCiYeH             head = self.read_head;
580*52da9a59SGnoCiYeH 
581*52da9a59SGnoCiYeH             loop {
582*52da9a59SGnoCiYeH                 // 消除多字节字符
583*52da9a59SGnoCiYeH                 head -= 1;
584*52da9a59SGnoCiYeH                 c = self.read_buf[ntty_buf_mask(head)];
585*52da9a59SGnoCiYeH 
586*52da9a59SGnoCiYeH                 if !(Self::is_continuation(c, termios)
587*52da9a59SGnoCiYeH                     && ntty_buf_mask(head) != ntty_buf_mask(self.canon_head))
588*52da9a59SGnoCiYeH                 {
589*52da9a59SGnoCiYeH                     break;
590*52da9a59SGnoCiYeH                 }
591*52da9a59SGnoCiYeH             }
592*52da9a59SGnoCiYeH 
593*52da9a59SGnoCiYeH             if Self::is_continuation(c, termios) {
594*52da9a59SGnoCiYeH                 break;
595*52da9a59SGnoCiYeH             }
596*52da9a59SGnoCiYeH 
597*52da9a59SGnoCiYeH             if werase {
598*52da9a59SGnoCiYeH                 todo!()
599*52da9a59SGnoCiYeH             }
600*52da9a59SGnoCiYeH 
601*52da9a59SGnoCiYeH             cnt = self.read_head - head;
602*52da9a59SGnoCiYeH             self.read_head = head;
603*52da9a59SGnoCiYeH             if termios.local_mode.contains(LocalMode::ECHO) {
604*52da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::ECHOPRT) {
605*52da9a59SGnoCiYeH                     if !self.erasing {
606*52da9a59SGnoCiYeH                         self.echo_char_raw(b'\\');
607*52da9a59SGnoCiYeH                         self.erasing = true;
608*52da9a59SGnoCiYeH                     }
609*52da9a59SGnoCiYeH                     self.echo_char(c, termios);
610*52da9a59SGnoCiYeH                     cnt -= 1;
611*52da9a59SGnoCiYeH                     while cnt > 0 {
612*52da9a59SGnoCiYeH                         cnt -= 1;
613*52da9a59SGnoCiYeH                         head += 1;
614*52da9a59SGnoCiYeH                         self.echo_char_raw(self.read_buf[ntty_buf_mask(head)]);
615*52da9a59SGnoCiYeH                         self.add_echo_byte(EchoOperation::Start.to_u8());
616*52da9a59SGnoCiYeH                         self.add_echo_byte(EchoOperation::MoveBackCol.to_u8());
617*52da9a59SGnoCiYeH                     }
618*52da9a59SGnoCiYeH                 } else if erase && !termios.local_mode.contains(LocalMode::ECHOE) {
619*52da9a59SGnoCiYeH                     self.echo_char(
620*52da9a59SGnoCiYeH                         termios.control_characters[ControlCharIndex::VERASE],
621*52da9a59SGnoCiYeH                         termios,
622*52da9a59SGnoCiYeH                     );
623*52da9a59SGnoCiYeH                 } else if c == b'\t' {
624*52da9a59SGnoCiYeH                     let mut num_chars = 0;
625*52da9a59SGnoCiYeH                     let mut after_tab = false;
626*52da9a59SGnoCiYeH                     let mut tail = self.read_head;
627*52da9a59SGnoCiYeH 
628*52da9a59SGnoCiYeH                     while ntty_buf_mask(tail) != ntty_buf_mask(self.canon_head) {
629*52da9a59SGnoCiYeH                         tail -= 1;
630*52da9a59SGnoCiYeH                         c = self.read_buf[ntty_buf_mask(tail)];
631*52da9a59SGnoCiYeH                         if c == b'\t' {
632*52da9a59SGnoCiYeH                             after_tab = true;
633*52da9a59SGnoCiYeH                             break;
634*52da9a59SGnoCiYeH                         } else if (c as char).is_control() {
635*52da9a59SGnoCiYeH                             if termios.local_mode.contains(LocalMode::ECHOCTL) {
636*52da9a59SGnoCiYeH                                 num_chars += 2;
637*52da9a59SGnoCiYeH                             }
638*52da9a59SGnoCiYeH                         } else if !Self::is_continuation(c, termios) {
639*52da9a59SGnoCiYeH                             num_chars += 1;
640*52da9a59SGnoCiYeH                         }
641*52da9a59SGnoCiYeH                     }
642*52da9a59SGnoCiYeH 
643*52da9a59SGnoCiYeH                     self.echo_erase_tab(num_chars, after_tab);
644*52da9a59SGnoCiYeH                 } else {
645*52da9a59SGnoCiYeH                     if (c as char).is_control() && termios.local_mode.contains(LocalMode::ECHOCTL) {
646*52da9a59SGnoCiYeH                         // 8 => '\b'
647*52da9a59SGnoCiYeH                         self.echo_char_raw(8);
648*52da9a59SGnoCiYeH                         self.echo_char_raw(b' ');
649*52da9a59SGnoCiYeH                         self.echo_char_raw(8);
650*52da9a59SGnoCiYeH                     }
651*52da9a59SGnoCiYeH 
652*52da9a59SGnoCiYeH                     if !(c as char).is_control() || termios.local_mode.contains(LocalMode::ECHOCTL)
653*52da9a59SGnoCiYeH                     {
654*52da9a59SGnoCiYeH                         // 8 => '\b'
655*52da9a59SGnoCiYeH                         self.echo_char_raw(8);
656*52da9a59SGnoCiYeH                         self.echo_char_raw(b' ');
657*52da9a59SGnoCiYeH                         self.echo_char_raw(8);
658*52da9a59SGnoCiYeH                     }
659*52da9a59SGnoCiYeH                 }
660*52da9a59SGnoCiYeH             }
661*52da9a59SGnoCiYeH 
662*52da9a59SGnoCiYeH             if erase {
663*52da9a59SGnoCiYeH                 break;
664*52da9a59SGnoCiYeH             }
665*52da9a59SGnoCiYeH         }
666*52da9a59SGnoCiYeH 
667*52da9a59SGnoCiYeH         if self.read_head == self.canon_head && termios.local_mode.contains(LocalMode::ECHO) {
668*52da9a59SGnoCiYeH             self.finish_erasing();
669*52da9a59SGnoCiYeH         }
670*52da9a59SGnoCiYeH     }
671*52da9a59SGnoCiYeH 
672*52da9a59SGnoCiYeH     fn finish_erasing(&mut self) {
673*52da9a59SGnoCiYeH         if self.erasing {
674*52da9a59SGnoCiYeH             self.echo_char_raw(b'/');
675*52da9a59SGnoCiYeH             self.erasing = false;
676*52da9a59SGnoCiYeH         }
677*52da9a59SGnoCiYeH     }
678*52da9a59SGnoCiYeH 
679*52da9a59SGnoCiYeH     fn echo_erase_tab(&mut self, mut num: u8, after_tab: bool) {
680*52da9a59SGnoCiYeH         self.add_echo_byte(EchoOperation::Start.to_u8());
681*52da9a59SGnoCiYeH         self.add_echo_byte(EchoOperation::EraseTab.to_u8());
682*52da9a59SGnoCiYeH 
683*52da9a59SGnoCiYeH         num &= 7;
684*52da9a59SGnoCiYeH 
685*52da9a59SGnoCiYeH         if after_tab {
686*52da9a59SGnoCiYeH             num |= 0x80;
687*52da9a59SGnoCiYeH         }
688*52da9a59SGnoCiYeH 
689*52da9a59SGnoCiYeH         self.add_echo_byte(num);
690*52da9a59SGnoCiYeH     }
691*52da9a59SGnoCiYeH 
692*52da9a59SGnoCiYeH     /// ## 多字节字符检测
693*52da9a59SGnoCiYeH     /// 检测是否为多字节字符的后续字节
694*52da9a59SGnoCiYeH     fn is_continuation(c: u8, termios: &RwLockReadGuard<Termios>) -> bool {
695*52da9a59SGnoCiYeH         return termios.input_mode.contains(InputMode::IUTF8) && (c & 0xc0) == 0x80;
696*52da9a59SGnoCiYeH     }
697*52da9a59SGnoCiYeH 
698*52da9a59SGnoCiYeH     /// ## 该字符是否已经当做流控字符处理
699*52da9a59SGnoCiYeH     pub fn is_flow_ctrl_char(&mut self, tty: Arc<TtyCore>, c: u8, lookahead_done: bool) -> bool {
700*52da9a59SGnoCiYeH         let termios = tty.core().termios();
701*52da9a59SGnoCiYeH 
702*52da9a59SGnoCiYeH         if !(termios.control_characters[ControlCharIndex::VSTART] == c
703*52da9a59SGnoCiYeH             || termios.control_characters[ControlCharIndex::VSTOP] == c)
704*52da9a59SGnoCiYeH         {
705*52da9a59SGnoCiYeH             return false;
706*52da9a59SGnoCiYeH         }
707*52da9a59SGnoCiYeH 
708*52da9a59SGnoCiYeH         if lookahead_done {
709*52da9a59SGnoCiYeH             return true;
710*52da9a59SGnoCiYeH         }
711*52da9a59SGnoCiYeH 
712*52da9a59SGnoCiYeH         if termios.control_characters[ControlCharIndex::VSTART] == c {
713*52da9a59SGnoCiYeH             tty.tty_start();
714*52da9a59SGnoCiYeH             self.process_echoes(tty.clone());
715*52da9a59SGnoCiYeH             return true;
716*52da9a59SGnoCiYeH         } else {
717*52da9a59SGnoCiYeH             tty.tty_stop();
718*52da9a59SGnoCiYeH             return true;
719*52da9a59SGnoCiYeH         }
720*52da9a59SGnoCiYeH     }
721*52da9a59SGnoCiYeH 
722*52da9a59SGnoCiYeH     /// ## 接收到信号字符时的处理
723*52da9a59SGnoCiYeH     fn recv_sig_char(
724*52da9a59SGnoCiYeH         &mut self,
725*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
726*52da9a59SGnoCiYeH         termios: &RwLockReadGuard<Termios>,
727*52da9a59SGnoCiYeH         signal: Signal,
728*52da9a59SGnoCiYeH         c: u8,
729*52da9a59SGnoCiYeH     ) {
730*52da9a59SGnoCiYeH         self.input_signal(tty.clone(), termios, signal);
731*52da9a59SGnoCiYeH         if termios.input_mode.contains(InputMode::IXON) {
732*52da9a59SGnoCiYeH             tty.tty_start();
733*52da9a59SGnoCiYeH         }
734*52da9a59SGnoCiYeH 
735*52da9a59SGnoCiYeH         if termios.local_mode.contains(LocalMode::ECHO) {
736*52da9a59SGnoCiYeH             self.echo_char(c, termios);
737*52da9a59SGnoCiYeH             self.commit_echoes(tty);
738*52da9a59SGnoCiYeH         } else {
739*52da9a59SGnoCiYeH             self.process_echoes(tty);
740*52da9a59SGnoCiYeH         }
741*52da9a59SGnoCiYeH     }
742*52da9a59SGnoCiYeH 
743*52da9a59SGnoCiYeH     /// ## 处理输入信号
744*52da9a59SGnoCiYeH     pub fn input_signal(
745*52da9a59SGnoCiYeH         &mut self,
746*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
747*52da9a59SGnoCiYeH         termios: &RwLockReadGuard<Termios>,
748*52da9a59SGnoCiYeH         signal: Signal,
749*52da9a59SGnoCiYeH     ) {
750*52da9a59SGnoCiYeH         // 先处理信号
751*52da9a59SGnoCiYeH         let mut ctrl_info = tty.core().contorl_info_irqsave();
752*52da9a59SGnoCiYeH         let pg = ctrl_info.pgid;
753*52da9a59SGnoCiYeH         if pg.is_some() {
754*52da9a59SGnoCiYeH             let _ = Syscall::kill(pg.unwrap(), signal as i32);
755*52da9a59SGnoCiYeH         }
756*52da9a59SGnoCiYeH 
757*52da9a59SGnoCiYeH         ctrl_info.pgid = None;
758*52da9a59SGnoCiYeH         ctrl_info.session = None;
759*52da9a59SGnoCiYeH 
760*52da9a59SGnoCiYeH         if !termios.local_mode.contains(LocalMode::NOFLSH) {
761*52da9a59SGnoCiYeH             // 重置
762*52da9a59SGnoCiYeH             self.echo_head = 0;
763*52da9a59SGnoCiYeH             self.echo_tail = 0;
764*52da9a59SGnoCiYeH             self.echo_mark = 0;
765*52da9a59SGnoCiYeH             self.echo_commit = 0;
766*52da9a59SGnoCiYeH 
767*52da9a59SGnoCiYeH             let _ = tty.flush_buffer(tty.core());
768*52da9a59SGnoCiYeH 
769*52da9a59SGnoCiYeH             self.read_head = 0;
770*52da9a59SGnoCiYeH             self.canon_head = 0;
771*52da9a59SGnoCiYeH             self.read_tail = 0;
772*52da9a59SGnoCiYeH             self.line_start = 0;
773*52da9a59SGnoCiYeH 
774*52da9a59SGnoCiYeH             self.erasing = false;
775*52da9a59SGnoCiYeH             self.read_flags.set_all(false);
776*52da9a59SGnoCiYeH             self.pushing = false;
777*52da9a59SGnoCiYeH             self.lookahead_count = 0;
778*52da9a59SGnoCiYeH         }
779*52da9a59SGnoCiYeH     }
780*52da9a59SGnoCiYeH 
781*52da9a59SGnoCiYeH     pub fn receive_char(&mut self, c: u8, tty: Arc<TtyCore>) {
782*52da9a59SGnoCiYeH         let termios = tty.core().termios();
783*52da9a59SGnoCiYeH 
784*52da9a59SGnoCiYeH         if termios.local_mode.contains(LocalMode::ECHO) {
785*52da9a59SGnoCiYeH             if self.erasing {
786*52da9a59SGnoCiYeH                 self.add_echo_byte(b'/');
787*52da9a59SGnoCiYeH                 self.erasing = false;
788*52da9a59SGnoCiYeH             }
789*52da9a59SGnoCiYeH 
790*52da9a59SGnoCiYeH             if self.canon_head == self.read_head {
791*52da9a59SGnoCiYeH                 self.add_echo_byte(EchoOperation::Start.to_u8());
792*52da9a59SGnoCiYeH                 self.add_echo_byte(EchoOperation::SetCanonCol.to_u8());
793*52da9a59SGnoCiYeH             }
794*52da9a59SGnoCiYeH 
795*52da9a59SGnoCiYeH             self.echo_char(c, &termios);
796*52da9a59SGnoCiYeH             self.commit_echoes(tty.clone());
797*52da9a59SGnoCiYeH         }
798*52da9a59SGnoCiYeH 
799*52da9a59SGnoCiYeH         if c == 0o377 && tty.core().termios().input_mode.contains(InputMode::PARMRK) {
800*52da9a59SGnoCiYeH             self.add_read_byte(c);
801*52da9a59SGnoCiYeH         }
802*52da9a59SGnoCiYeH         self.add_read_byte(c);
803*52da9a59SGnoCiYeH     }
804*52da9a59SGnoCiYeH 
805*52da9a59SGnoCiYeH     pub fn echo_char(&mut self, c: u8, termios: &RwLockReadGuard<Termios>) {
806*52da9a59SGnoCiYeH         if c == EchoOperation::Start.to_u8() {
807*52da9a59SGnoCiYeH             self.add_echo_byte(EchoOperation::Start.to_u8());
808*52da9a59SGnoCiYeH             self.add_echo_byte(EchoOperation::Start.to_u8());
809*52da9a59SGnoCiYeH         } else {
810*52da9a59SGnoCiYeH             if termios.local_mode.contains(LocalMode::ECHOCTL)
811*52da9a59SGnoCiYeH                 && (c as char).is_control()
812*52da9a59SGnoCiYeH                 && c != b'\t'
813*52da9a59SGnoCiYeH             {
814*52da9a59SGnoCiYeH                 self.add_echo_byte(EchoOperation::Start.to_u8());
815*52da9a59SGnoCiYeH             }
816*52da9a59SGnoCiYeH             self.add_echo_byte(c);
817*52da9a59SGnoCiYeH         }
818*52da9a59SGnoCiYeH     }
819*52da9a59SGnoCiYeH 
820*52da9a59SGnoCiYeH     pub fn echo_char_raw(&mut self, c: u8) {
821*52da9a59SGnoCiYeH         if c == EchoOperation::Start.to_u8() {
822*52da9a59SGnoCiYeH             self.add_echo_byte(EchoOperation::Start.to_u8());
823*52da9a59SGnoCiYeH             self.add_echo_byte(EchoOperation::Start.to_u8());
824*52da9a59SGnoCiYeH         } else {
825*52da9a59SGnoCiYeH             self.add_echo_byte(c);
826*52da9a59SGnoCiYeH         }
827*52da9a59SGnoCiYeH     }
828*52da9a59SGnoCiYeH 
829*52da9a59SGnoCiYeH     /// ## 提交echobuf里的数据显示
830*52da9a59SGnoCiYeH     pub fn commit_echoes(&mut self, tty: Arc<TtyCore>) {
831*52da9a59SGnoCiYeH         let head = self.echo_head;
832*52da9a59SGnoCiYeH         self.echo_mark = head;
833*52da9a59SGnoCiYeH         let old = self.echo_commit - self.echo_tail;
834*52da9a59SGnoCiYeH 
835*52da9a59SGnoCiYeH         // 需要echo的字符个数
836*52da9a59SGnoCiYeH         let nr = head - self.echo_tail;
837*52da9a59SGnoCiYeH 
838*52da9a59SGnoCiYeH         if nr < ECHO_COMMIT_WATERMARK || nr % ECHO_BLOCK > old % ECHO_BLOCK {
839*52da9a59SGnoCiYeH             return;
840*52da9a59SGnoCiYeH         }
841*52da9a59SGnoCiYeH 
842*52da9a59SGnoCiYeH         self.echo_commit = head;
843*52da9a59SGnoCiYeH         let echoed = self.echoes(tty.clone());
844*52da9a59SGnoCiYeH 
845*52da9a59SGnoCiYeH         if echoed.is_ok() && echoed.unwrap() > 0 {
846*52da9a59SGnoCiYeH             tty.flush_chars(tty.core());
847*52da9a59SGnoCiYeH         }
848*52da9a59SGnoCiYeH     }
849*52da9a59SGnoCiYeH 
850*52da9a59SGnoCiYeH     pub fn add_echo_byte(&mut self, c: u8) {
851*52da9a59SGnoCiYeH         self.echo_buf[ntty_buf_mask(self.echo_head)] = c;
852*52da9a59SGnoCiYeH         self.echo_head += 1;
853*52da9a59SGnoCiYeH     }
854*52da9a59SGnoCiYeH 
855*52da9a59SGnoCiYeH     pub fn add_read_byte(&mut self, c: u8) {
856*52da9a59SGnoCiYeH         self.read_buf[ntty_buf_mask(self.read_head)] = c;
857*52da9a59SGnoCiYeH         self.read_head += 1;
858*52da9a59SGnoCiYeH     }
859*52da9a59SGnoCiYeH 
860*52da9a59SGnoCiYeH     /// ### 将read_buffer的部分值置0
861*52da9a59SGnoCiYeH     ///
862*52da9a59SGnoCiYeH     /// 只会在规范模式和禁用echo下执行
863*52da9a59SGnoCiYeH     #[inline]
864*52da9a59SGnoCiYeH     pub fn zero_buffer(&mut self, offset: usize, size: usize) {
865*52da9a59SGnoCiYeH         let offset = offset & (NTTY_BUFSIZE - 1);
866*52da9a59SGnoCiYeH         if self.icanon && !self.echo {
867*52da9a59SGnoCiYeH             let n = offset + size;
868*52da9a59SGnoCiYeH             if n > NTTY_BUFSIZE {
869*52da9a59SGnoCiYeH                 for c in &mut self.read_buf[offset..NTTY_BUFSIZE] {
870*52da9a59SGnoCiYeH                     *c = 0
871*52da9a59SGnoCiYeH                 }
872*52da9a59SGnoCiYeH 
873*52da9a59SGnoCiYeH                 for c in &mut self.read_buf[0..(n - NTTY_BUFSIZE)] {
874*52da9a59SGnoCiYeH                     *c = 0
875*52da9a59SGnoCiYeH                 }
876*52da9a59SGnoCiYeH             } else {
877*52da9a59SGnoCiYeH                 for c in &mut self.read_buf[offset..n] {
878*52da9a59SGnoCiYeH                     *c = 0
879*52da9a59SGnoCiYeH                 }
880*52da9a59SGnoCiYeH             };
881*52da9a59SGnoCiYeH         }
882*52da9a59SGnoCiYeH     }
883*52da9a59SGnoCiYeH 
884*52da9a59SGnoCiYeH     /// ## 从ntty中拷贝数据
885*52da9a59SGnoCiYeH     ///
886*52da9a59SGnoCiYeH     /// ### 参数
887*52da9a59SGnoCiYeH     ///
888*52da9a59SGnoCiYeH     /// ### to: 存储数据
889*52da9a59SGnoCiYeH     /// ### tail: 读取尾
890*52da9a59SGnoCiYeH     pub fn ntty_copy(
891*52da9a59SGnoCiYeH         &mut self,
892*52da9a59SGnoCiYeH         to: &mut [u8],
893*52da9a59SGnoCiYeH         tail: usize,
894*52da9a59SGnoCiYeH         n: &mut usize,
895*52da9a59SGnoCiYeH     ) -> Result<(), SystemError> {
896*52da9a59SGnoCiYeH         if to.len() < *n {
897*52da9a59SGnoCiYeH             *n = to.len();
898*52da9a59SGnoCiYeH             // return Err(SystemError::EINVAL);
899*52da9a59SGnoCiYeH         }
900*52da9a59SGnoCiYeH         if tail > NTTY_BUFSIZE {
901*52da9a59SGnoCiYeH             return Err(SystemError::EINVAL);
902*52da9a59SGnoCiYeH         }
903*52da9a59SGnoCiYeH 
904*52da9a59SGnoCiYeH         let size = NTTY_BUFSIZE - tail;
905*52da9a59SGnoCiYeH 
906*52da9a59SGnoCiYeH         if size < *n {
907*52da9a59SGnoCiYeH             // 有一部分数据在头部,则先拷贝后面部分,再拷贝头部
908*52da9a59SGnoCiYeH             // TODO: tty审计?
909*52da9a59SGnoCiYeH             to[0..size].copy_from_slice(&self.read_buf[tail..(tail + size)]);
910*52da9a59SGnoCiYeH             to[size..].copy_from_slice(&self.read_buf[(tail + size)..(*n + tail)]);
911*52da9a59SGnoCiYeH         } else {
912*52da9a59SGnoCiYeH             to[..*n].copy_from_slice(&self.read_buf[tail..(tail + *n)])
913*52da9a59SGnoCiYeH         }
914*52da9a59SGnoCiYeH 
915*52da9a59SGnoCiYeH         self.zero_buffer(tail, *n);
916*52da9a59SGnoCiYeH 
917*52da9a59SGnoCiYeH         Ok(())
918*52da9a59SGnoCiYeH     }
919*52da9a59SGnoCiYeH 
920*52da9a59SGnoCiYeH     /// ## 规范模式下跳过EOF
921*52da9a59SGnoCiYeH     pub fn canon_skip_eof(&mut self) {
922*52da9a59SGnoCiYeH         // 没有数据
923*52da9a59SGnoCiYeH         if self.read_tail == self.canon_head {
924*52da9a59SGnoCiYeH             return;
925*52da9a59SGnoCiYeH         }
926*52da9a59SGnoCiYeH 
927*52da9a59SGnoCiYeH         let tail = self.read_tail & (NTTY_BUFSIZE - 1);
928*52da9a59SGnoCiYeH 
929*52da9a59SGnoCiYeH         // 查看read_flags是否读取位置为特殊字符
930*52da9a59SGnoCiYeH         if !self.read_flags.get(tail).unwrap() {
931*52da9a59SGnoCiYeH             return;
932*52da9a59SGnoCiYeH         }
933*52da9a59SGnoCiYeH 
934*52da9a59SGnoCiYeH         // 确保读取位置是'\0'字符
935*52da9a59SGnoCiYeH         if self.read_buf[tail] != ControlCharIndex::DISABLE_CHAR {
936*52da9a59SGnoCiYeH             return;
937*52da9a59SGnoCiYeH         }
938*52da9a59SGnoCiYeH 
939*52da9a59SGnoCiYeH         // 处理该字符,将read_flagsw该位清除
940*52da9a59SGnoCiYeH         self.read_flags.set(tail, false);
941*52da9a59SGnoCiYeH         // 读取位置+1,即跳过该字符不做处理
942*52da9a59SGnoCiYeH         self.read_tail += 1;
943*52da9a59SGnoCiYeH     }
944*52da9a59SGnoCiYeH 
945*52da9a59SGnoCiYeH     /// ## 在规范模式(canonical mode)下从读缓冲中复制一行
946*52da9a59SGnoCiYeH     ///
947*52da9a59SGnoCiYeH     /// 一次只拷贝一行
948*52da9a59SGnoCiYeH     ///
949*52da9a59SGnoCiYeH     /// ## 参数
950*52da9a59SGnoCiYeH     /// ### dst: 存放数据
951*52da9a59SGnoCiYeH     /// ### nr: 需要拷贝的数据大小
952*52da9a59SGnoCiYeH     ///
953*52da9a59SGnoCiYeH     /// ## 返回值
954*52da9a59SGnoCiYeH     /// ### true: 表示一行未结束并且还有数据可读
955*52da9a59SGnoCiYeH     /// ### false: 一行已结束或者没有数据可读
956*52da9a59SGnoCiYeH     pub fn canon_copy_from_read_buf(
957*52da9a59SGnoCiYeH         &mut self,
958*52da9a59SGnoCiYeH         dst: &mut [u8],
959*52da9a59SGnoCiYeH         nr: &mut usize,
960*52da9a59SGnoCiYeH         offset: &mut usize,
961*52da9a59SGnoCiYeH     ) -> Result<bool, SystemError> {
962*52da9a59SGnoCiYeH         if *nr == 0 {
963*52da9a59SGnoCiYeH             return Ok(false);
964*52da9a59SGnoCiYeH         }
965*52da9a59SGnoCiYeH 
966*52da9a59SGnoCiYeH         let canon_head = self.canon_head;
967*52da9a59SGnoCiYeH 
968*52da9a59SGnoCiYeH         // 取得能够读到的字符数,即canon_head - self.read_tail和nr最小值
969*52da9a59SGnoCiYeH         let mut n = (*nr).min(canon_head - self.read_tail);
970*52da9a59SGnoCiYeH 
971*52da9a59SGnoCiYeH         // 获得读尾index
972*52da9a59SGnoCiYeH         let tail = self.read_tail & (NTTY_BUFSIZE - 1);
973*52da9a59SGnoCiYeH 
974*52da9a59SGnoCiYeH         // 避免越界,这个size才是实际读取大小
975*52da9a59SGnoCiYeH         let size = if tail + n > NTTY_BUFSIZE {
976*52da9a59SGnoCiYeH             NTTY_BUFSIZE
977*52da9a59SGnoCiYeH         } else {
978*52da9a59SGnoCiYeH             tail + *nr
979*52da9a59SGnoCiYeH         };
980*52da9a59SGnoCiYeH 
981*52da9a59SGnoCiYeH         // 找到eol的坐标
982*52da9a59SGnoCiYeH         let tmp = self.read_flags.next_index(tail);
983*52da9a59SGnoCiYeH         // 找到的话即为坐标,未找到的话即为NTTY_BUFSIZE
984*52da9a59SGnoCiYeH         let mut eol = if tmp.is_none() { size } else { tmp.unwrap() };
985*52da9a59SGnoCiYeH         if eol > size {
986*52da9a59SGnoCiYeH             eol = size
987*52da9a59SGnoCiYeH         }
988*52da9a59SGnoCiYeH 
989*52da9a59SGnoCiYeH         // 是否需要绕回缓冲区头部
990*52da9a59SGnoCiYeH         let more = n - (size - tail);
991*52da9a59SGnoCiYeH 
992*52da9a59SGnoCiYeH         // 是否找到eol
993*52da9a59SGnoCiYeH         let found = if eol == NTTY_BUFSIZE && more > 0 {
994*52da9a59SGnoCiYeH             // 需要返回头部
995*52da9a59SGnoCiYeH             let ret = self.read_flags.first_index();
996*52da9a59SGnoCiYeH             if ret.is_some() {
997*52da9a59SGnoCiYeH                 let tmp = ret.unwrap();
998*52da9a59SGnoCiYeH                 // 在头部范围内找到eol
999*52da9a59SGnoCiYeH                 if tmp < more {
1000*52da9a59SGnoCiYeH                     eol = tmp;
1001*52da9a59SGnoCiYeH                 }
1002*52da9a59SGnoCiYeH             } else {
1003*52da9a59SGnoCiYeH                 eol = more;
1004*52da9a59SGnoCiYeH             }
1005*52da9a59SGnoCiYeH             eol != more
1006*52da9a59SGnoCiYeH         } else {
1007*52da9a59SGnoCiYeH             // 不需要返回头部
1008*52da9a59SGnoCiYeH             eol != size
1009*52da9a59SGnoCiYeH         };
1010*52da9a59SGnoCiYeH 
1011*52da9a59SGnoCiYeH         n = eol - tail;
1012*52da9a59SGnoCiYeH         if n > NTTY_BUFSIZE {
1013*52da9a59SGnoCiYeH             // 减法溢出则加上BUFSIZE即可限制在0-NTTY_BUFSIZE内
1014*52da9a59SGnoCiYeH             n += NTTY_BUFSIZE;
1015*52da9a59SGnoCiYeH         }
1016*52da9a59SGnoCiYeH 
1017*52da9a59SGnoCiYeH         // 规范模式下实际扫描过的字符数,需要将eol计算在内
1018*52da9a59SGnoCiYeH         let count = if found { n + 1 } else { n };
1019*52da9a59SGnoCiYeH 
1020*52da9a59SGnoCiYeH         // 表示这一行未结束
1021*52da9a59SGnoCiYeH         if !found || self.read_at(eol) != ControlCharIndex::DISABLE_CHAR {
1022*52da9a59SGnoCiYeH             n = count;
1023*52da9a59SGnoCiYeH         }
1024*52da9a59SGnoCiYeH 
1025*52da9a59SGnoCiYeH         self.ntty_copy(&mut dst[*offset..], tail, &mut n)?;
1026*52da9a59SGnoCiYeH         *nr -= n;
1027*52da9a59SGnoCiYeH         *offset += n;
1028*52da9a59SGnoCiYeH 
1029*52da9a59SGnoCiYeH         if found {
1030*52da9a59SGnoCiYeH             self.read_flags.set(eol, false);
1031*52da9a59SGnoCiYeH         }
1032*52da9a59SGnoCiYeH 
1033*52da9a59SGnoCiYeH         self.read_tail += count;
1034*52da9a59SGnoCiYeH 
1035*52da9a59SGnoCiYeH         if found {
1036*52da9a59SGnoCiYeH             if !self.pushing {
1037*52da9a59SGnoCiYeH                 self.line_start = self.read_tail;
1038*52da9a59SGnoCiYeH             } else {
1039*52da9a59SGnoCiYeH                 self.pushing = false;
1040*52da9a59SGnoCiYeH             }
1041*52da9a59SGnoCiYeH 
1042*52da9a59SGnoCiYeH             // todo: 审计?
1043*52da9a59SGnoCiYeH             return Ok(false);
1044*52da9a59SGnoCiYeH         }
1045*52da9a59SGnoCiYeH 
1046*52da9a59SGnoCiYeH         // 这里是表示没有找到eol,根据是否还有数据可读返回
1047*52da9a59SGnoCiYeH         Ok(self.read_tail != canon_head)
1048*52da9a59SGnoCiYeH     }
1049*52da9a59SGnoCiYeH 
1050*52da9a59SGnoCiYeH     /// ## 根据终端的模式和输入缓冲区中的数据量,判断是否可读字符
1051*52da9a59SGnoCiYeH     pub fn input_available(&self, termios: RwLockReadGuard<Termios>, poll: bool) -> bool {
1052*52da9a59SGnoCiYeH         // 计算最小字符数
1053*52da9a59SGnoCiYeH         let amt = if poll
1054*52da9a59SGnoCiYeH             && termios.control_characters[ControlCharIndex::VTIME] as u32 == 0
1055*52da9a59SGnoCiYeH             && termios.control_characters[ControlCharIndex::VMIN] as u32 != 0
1056*52da9a59SGnoCiYeH         {
1057*52da9a59SGnoCiYeH             termios.control_characters[ControlCharIndex::VMIN] as usize
1058*52da9a59SGnoCiYeH         } else {
1059*52da9a59SGnoCiYeH             1
1060*52da9a59SGnoCiYeH         };
1061*52da9a59SGnoCiYeH 
1062*52da9a59SGnoCiYeH         // 规范模式且非拓展
1063*52da9a59SGnoCiYeH         if self.icanon && !termios.local_mode.contains(LocalMode::EXTPROC) {
1064*52da9a59SGnoCiYeH             return self.canon_head != self.read_tail;
1065*52da9a59SGnoCiYeH         } else {
1066*52da9a59SGnoCiYeH             return (self.commit_head - self.read_tail) >= amt;
1067*52da9a59SGnoCiYeH         }
1068*52da9a59SGnoCiYeH     }
1069*52da9a59SGnoCiYeH 
1070*52da9a59SGnoCiYeH     /// ## 非规范模式下从read_buf读取数据
1071*52da9a59SGnoCiYeH     ///
1072*52da9a59SGnoCiYeH     /// ## 参数
1073*52da9a59SGnoCiYeH     /// ### termios: tty对应的termioss读锁守卫
1074*52da9a59SGnoCiYeH     /// ### dst: 存储读取数据
1075*52da9a59SGnoCiYeH     /// ### nr: 读取长度
1076*52da9a59SGnoCiYeH     ///
1077*52da9a59SGnoCiYeH     /// ## 返回值
1078*52da9a59SGnoCiYeH     /// ### true: 还有更多数据可读
1079*52da9a59SGnoCiYeH     /// ### false: 无更多数据可读
1080*52da9a59SGnoCiYeH     pub fn copy_from_read_buf(
1081*52da9a59SGnoCiYeH         &mut self,
1082*52da9a59SGnoCiYeH         termios: RwLockReadGuard<Termios>,
1083*52da9a59SGnoCiYeH         dst: &mut [u8],
1084*52da9a59SGnoCiYeH         nr: &mut usize,
1085*52da9a59SGnoCiYeH         offset: &mut usize,
1086*52da9a59SGnoCiYeH     ) -> Result<bool, SystemError> {
1087*52da9a59SGnoCiYeH         let head = self.commit_head;
1088*52da9a59SGnoCiYeH         let tail = self.read_tail & (NTTY_BUFSIZE - 1);
1089*52da9a59SGnoCiYeH 
1090*52da9a59SGnoCiYeH         // 计算出可读的字符数
1091*52da9a59SGnoCiYeH         let mut n = (NTTY_BUFSIZE - tail).min(self.read_tail);
1092*52da9a59SGnoCiYeH         n = n.min(*nr);
1093*52da9a59SGnoCiYeH 
1094*52da9a59SGnoCiYeH         if n > 0 {
1095*52da9a59SGnoCiYeH             // 拷贝数据
1096*52da9a59SGnoCiYeH             self.ntty_copy(&mut dst[*offset..], tail, &mut n)?;
1097*52da9a59SGnoCiYeH             // todo:审计?
1098*52da9a59SGnoCiYeH             self.read_tail += n;
1099*52da9a59SGnoCiYeH 
1100*52da9a59SGnoCiYeH             // 是否只读取了eof
1101*52da9a59SGnoCiYeH             let eof =
1102*52da9a59SGnoCiYeH                 n == 1 && self.read_buf[tail] == termios.control_characters[ControlCharIndex::VEOF];
1103*52da9a59SGnoCiYeH 
1104*52da9a59SGnoCiYeH             if termios.local_mode.contains(LocalMode::EXTPROC)
1105*52da9a59SGnoCiYeH                 && self.icanon
1106*52da9a59SGnoCiYeH                 && eof
1107*52da9a59SGnoCiYeH                 && head == self.read_tail
1108*52da9a59SGnoCiYeH             {
1109*52da9a59SGnoCiYeH                 return Ok(false);
1110*52da9a59SGnoCiYeH             }
1111*52da9a59SGnoCiYeH 
1112*52da9a59SGnoCiYeH             *nr -= n;
1113*52da9a59SGnoCiYeH             *offset += n;
1114*52da9a59SGnoCiYeH 
1115*52da9a59SGnoCiYeH             return Ok(head != self.read_tail);
1116*52da9a59SGnoCiYeH         }
1117*52da9a59SGnoCiYeH 
1118*52da9a59SGnoCiYeH         Ok(false)
1119*52da9a59SGnoCiYeH     }
1120*52da9a59SGnoCiYeH 
1121*52da9a59SGnoCiYeH     /// ## 用于处理带有 OPOST(Output Post-processing)标志的输出块的函数
1122*52da9a59SGnoCiYeH     /// OPOST 是 POSIX 终端驱动器标志之一,用于指定在写入终端设备之前对输出数据进行一些后期处理。
1123*52da9a59SGnoCiYeH     pub fn process_output_block(
1124*52da9a59SGnoCiYeH         &mut self,
1125*52da9a59SGnoCiYeH         core: &TtyCoreData,
1126*52da9a59SGnoCiYeH         termios: RwLockReadGuard<Termios>,
1127*52da9a59SGnoCiYeH         buf: &[u8],
1128*52da9a59SGnoCiYeH         nr: usize,
1129*52da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
1130*52da9a59SGnoCiYeH         let mut nr = nr;
1131*52da9a59SGnoCiYeH         let tty = self.tty.clone().unwrap().upgrade().unwrap();
1132*52da9a59SGnoCiYeH         let space = tty.write_room(tty.core());
1133*52da9a59SGnoCiYeH 
1134*52da9a59SGnoCiYeH         // 如果读取数量大于了可用空间,则取最小的为真正的写入数量
1135*52da9a59SGnoCiYeH         if nr > space {
1136*52da9a59SGnoCiYeH             nr = space
1137*52da9a59SGnoCiYeH         }
1138*52da9a59SGnoCiYeH 
1139*52da9a59SGnoCiYeH         let mut cnt = 0;
1140*52da9a59SGnoCiYeH         for i in 0..nr {
1141*52da9a59SGnoCiYeH             cnt = i;
1142*52da9a59SGnoCiYeH             let c = buf[i];
1143*52da9a59SGnoCiYeH             if c as usize == 8 {
1144*52da9a59SGnoCiYeH                 // 表示退格
1145*52da9a59SGnoCiYeH                 if self.cursor_column > 0 {
1146*52da9a59SGnoCiYeH                     self.cursor_column -= 1;
1147*52da9a59SGnoCiYeH                 }
1148*52da9a59SGnoCiYeH                 continue;
1149*52da9a59SGnoCiYeH             }
1150*52da9a59SGnoCiYeH             match c as char {
1151*52da9a59SGnoCiYeH                 '\n' => {
1152*52da9a59SGnoCiYeH                     if termios.output_mode.contains(OutputMode::ONLRET) {
1153*52da9a59SGnoCiYeH                         // 将回车映射为\n,即将\n换为回车
1154*52da9a59SGnoCiYeH                         self.cursor_column = 0;
1155*52da9a59SGnoCiYeH                     }
1156*52da9a59SGnoCiYeH                     if termios.output_mode.contains(OutputMode::ONLCR) {
1157*52da9a59SGnoCiYeH                         // 输出时将\n换为\r\n
1158*52da9a59SGnoCiYeH                         break;
1159*52da9a59SGnoCiYeH                     }
1160*52da9a59SGnoCiYeH 
1161*52da9a59SGnoCiYeH                     self.canon_cursor_column = self.cursor_column;
1162*52da9a59SGnoCiYeH                 }
1163*52da9a59SGnoCiYeH                 '\r' => {
1164*52da9a59SGnoCiYeH                     if termios.output_mode.contains(OutputMode::ONOCR) && self.cursor_column == 0 {
1165*52da9a59SGnoCiYeH                         // 光标已经在第0列,则不输出回车符
1166*52da9a59SGnoCiYeH                         break;
1167*52da9a59SGnoCiYeH                     }
1168*52da9a59SGnoCiYeH 
1169*52da9a59SGnoCiYeH                     if termios.output_mode.contains(OutputMode::OCRNL) {
1170*52da9a59SGnoCiYeH                         break;
1171*52da9a59SGnoCiYeH                     }
1172*52da9a59SGnoCiYeH                     self.canon_cursor_column = self.cursor_column;
1173*52da9a59SGnoCiYeH                 }
1174*52da9a59SGnoCiYeH                 '\t' => {
1175*52da9a59SGnoCiYeH                     break;
1176*52da9a59SGnoCiYeH                 }
1177*52da9a59SGnoCiYeH                 _ => {
1178*52da9a59SGnoCiYeH                     // 判断是否为控制字符
1179*52da9a59SGnoCiYeH                     if !(c as char).is_control() {
1180*52da9a59SGnoCiYeH                         if termios.output_mode.contains(OutputMode::OLCUC) {
1181*52da9a59SGnoCiYeH                             break;
1182*52da9a59SGnoCiYeH                         }
1183*52da9a59SGnoCiYeH 
1184*52da9a59SGnoCiYeH                         // 判断是否为utf8模式下的连续字符
1185*52da9a59SGnoCiYeH                         if !(termios.input_mode.contains(InputMode::IUTF8)
1186*52da9a59SGnoCiYeH                             && (c as usize) & 0xc0 == 0x80)
1187*52da9a59SGnoCiYeH                         {
1188*52da9a59SGnoCiYeH                             self.cursor_column += 1;
1189*52da9a59SGnoCiYeH                         }
1190*52da9a59SGnoCiYeH                     }
1191*52da9a59SGnoCiYeH                 }
1192*52da9a59SGnoCiYeH             }
1193*52da9a59SGnoCiYeH         }
1194*52da9a59SGnoCiYeH 
1195*52da9a59SGnoCiYeH         drop(termios);
1196*52da9a59SGnoCiYeH         return tty.write(core, buf, cnt);
1197*52da9a59SGnoCiYeH     }
1198*52da9a59SGnoCiYeH 
1199*52da9a59SGnoCiYeH     /// ## 处理回显
1200*52da9a59SGnoCiYeH     pub fn process_echoes(&mut self, tty: Arc<TtyCore>) {
1201*52da9a59SGnoCiYeH         if self.echo_mark == self.echo_tail {
1202*52da9a59SGnoCiYeH             return;
1203*52da9a59SGnoCiYeH         }
1204*52da9a59SGnoCiYeH         self.echo_commit = self.echo_mark;
1205*52da9a59SGnoCiYeH         let echoed = self.echoes(tty.clone());
1206*52da9a59SGnoCiYeH 
1207*52da9a59SGnoCiYeH         if echoed.is_ok() && echoed.unwrap() > 0 {
1208*52da9a59SGnoCiYeH             let _ = tty.flush_chars(tty.core());
1209*52da9a59SGnoCiYeH         }
1210*52da9a59SGnoCiYeH     }
1211*52da9a59SGnoCiYeH 
1212*52da9a59SGnoCiYeH     pub fn echoes(&mut self, tty: Arc<TtyCore>) -> Result<usize, SystemError> {
1213*52da9a59SGnoCiYeH         let mut space = tty.write_room(tty.core());
1214*52da9a59SGnoCiYeH         let ospace = space;
1215*52da9a59SGnoCiYeH         let termios = tty.core().termios();
1216*52da9a59SGnoCiYeH         let core = tty.core();
1217*52da9a59SGnoCiYeH         let mut tail = self.echo_tail;
1218*52da9a59SGnoCiYeH 
1219*52da9a59SGnoCiYeH         while ntty_buf_mask(self.echo_commit) != ntty_buf_mask(tail) {
1220*52da9a59SGnoCiYeH             let c = self.echo_buf[ntty_buf_mask(tail)];
1221*52da9a59SGnoCiYeH 
1222*52da9a59SGnoCiYeH             if EchoOperation::from_u8(c) == EchoOperation::Start {
1223*52da9a59SGnoCiYeH                 if ntty_buf_mask(self.echo_commit) == ntty_buf_mask(tail + 1) {
1224*52da9a59SGnoCiYeH                     self.echo_tail = tail;
1225*52da9a59SGnoCiYeH                     return Ok(ospace - space);
1226*52da9a59SGnoCiYeH                 }
1227*52da9a59SGnoCiYeH 
1228*52da9a59SGnoCiYeH                 // 获取到start,之后取第一个作为op
1229*52da9a59SGnoCiYeH                 let op = EchoOperation::from_u8(self.echo_buf[ntty_buf_mask(tail + 1)]);
1230*52da9a59SGnoCiYeH 
1231*52da9a59SGnoCiYeH                 match op {
1232*52da9a59SGnoCiYeH                     EchoOperation::Start => {
1233*52da9a59SGnoCiYeH                         if space == 0 {
1234*52da9a59SGnoCiYeH                             break;
1235*52da9a59SGnoCiYeH                         }
1236*52da9a59SGnoCiYeH 
1237*52da9a59SGnoCiYeH                         if tty
1238*52da9a59SGnoCiYeH                             .put_char(tty.core(), EchoOperation::Start.to_u8())
1239*52da9a59SGnoCiYeH                             .is_err()
1240*52da9a59SGnoCiYeH                         {
1241*52da9a59SGnoCiYeH                             tty.write(core, &[EchoOperation::Start.to_u8()], 1)?;
1242*52da9a59SGnoCiYeH                         }
1243*52da9a59SGnoCiYeH 
1244*52da9a59SGnoCiYeH                         self.cursor_column += 1;
1245*52da9a59SGnoCiYeH                         space -= 1;
1246*52da9a59SGnoCiYeH                         tail += 2;
1247*52da9a59SGnoCiYeH                     }
1248*52da9a59SGnoCiYeH                     EchoOperation::MoveBackCol => {
1249*52da9a59SGnoCiYeH                         if self.cursor_column > 0 {
1250*52da9a59SGnoCiYeH                             self.cursor_column -= 1;
1251*52da9a59SGnoCiYeH                         }
1252*52da9a59SGnoCiYeH                         tail += 2;
1253*52da9a59SGnoCiYeH                     }
1254*52da9a59SGnoCiYeH                     EchoOperation::SetCanonCol => {
1255*52da9a59SGnoCiYeH                         self.canon_cursor_column = self.cursor_column;
1256*52da9a59SGnoCiYeH                         tail += 2;
1257*52da9a59SGnoCiYeH                     }
1258*52da9a59SGnoCiYeH                     EchoOperation::EraseTab => {
1259*52da9a59SGnoCiYeH                         if ntty_buf_mask(self.echo_commit) == ntty_buf_mask(tail + 2) {
1260*52da9a59SGnoCiYeH                             self.echo_tail = tail;
1261*52da9a59SGnoCiYeH                             return Ok(ospace - space);
1262*52da9a59SGnoCiYeH                         }
1263*52da9a59SGnoCiYeH 
1264*52da9a59SGnoCiYeH                         // 要擦除的制表符所占用的列数
1265*52da9a59SGnoCiYeH                         let mut char_num = self.echo_buf[ntty_buf_mask(tail + 2)] as usize;
1266*52da9a59SGnoCiYeH 
1267*52da9a59SGnoCiYeH                         /*
1268*52da9a59SGnoCiYeH                            如果 num_chars 的最高位(0x80)未设置,
1269*52da9a59SGnoCiYeH                            表示这是从输入的起始位置而不是从先前的制表符开始计算的列数。
1270*52da9a59SGnoCiYeH                            在这种情况下,将 num_chars 与 ldata->canon_column 相加,否则,列数就是正常的制表符列数。
1271*52da9a59SGnoCiYeH                         */
1272*52da9a59SGnoCiYeH                         if char_num & 0x80 == 0 {
1273*52da9a59SGnoCiYeH                             char_num += self.canon_cursor_column as usize;
1274*52da9a59SGnoCiYeH                         }
1275*52da9a59SGnoCiYeH 
1276*52da9a59SGnoCiYeH                         // 计算要回退的列数,即制表符宽度减去实际占用的列数
1277*52da9a59SGnoCiYeH                         let mut num_bs = 8 - (char_num & 7);
1278*52da9a59SGnoCiYeH                         if num_bs > space {
1279*52da9a59SGnoCiYeH                             // 表示左边没有足够空间回退
1280*52da9a59SGnoCiYeH                             break;
1281*52da9a59SGnoCiYeH                         }
1282*52da9a59SGnoCiYeH 
1283*52da9a59SGnoCiYeH                         space -= num_bs;
1284*52da9a59SGnoCiYeH                         while num_bs != 0 {
1285*52da9a59SGnoCiYeH                             num_bs -= 1;
1286*52da9a59SGnoCiYeH                             // 8 => '\b'
1287*52da9a59SGnoCiYeH                             if tty.put_char(tty.core(), 8).is_err() {
1288*52da9a59SGnoCiYeH                                 tty.write(core, &[8], 1)?;
1289*52da9a59SGnoCiYeH                             }
1290*52da9a59SGnoCiYeH 
1291*52da9a59SGnoCiYeH                             if self.cursor_column > 0 {
1292*52da9a59SGnoCiYeH                                 self.cursor_column -= 1;
1293*52da9a59SGnoCiYeH                             }
1294*52da9a59SGnoCiYeH                         }
1295*52da9a59SGnoCiYeH 
1296*52da9a59SGnoCiYeH                         // 已经读取了 tail tail+1 tail+2,所以这里偏移加3
1297*52da9a59SGnoCiYeH                         tail += 3;
1298*52da9a59SGnoCiYeH                     }
1299*52da9a59SGnoCiYeH                     EchoOperation::Undefined(ch) => {
1300*52da9a59SGnoCiYeH                         match ch {
1301*52da9a59SGnoCiYeH                             8 => {
1302*52da9a59SGnoCiYeH                                 if tty.put_char(tty.core(), 8).is_err() {
1303*52da9a59SGnoCiYeH                                     tty.write(core, &[8], 1)?;
1304*52da9a59SGnoCiYeH                                 }
1305*52da9a59SGnoCiYeH                                 if tty.put_char(tty.core(), ' ' as u8).is_err() {
1306*52da9a59SGnoCiYeH                                     tty.write(core, &[' ' as u8], 1)?;
1307*52da9a59SGnoCiYeH                                 }
1308*52da9a59SGnoCiYeH                                 self.cursor_column -= 1;
1309*52da9a59SGnoCiYeH                                 space -= 1;
1310*52da9a59SGnoCiYeH                                 tail += 1;
1311*52da9a59SGnoCiYeH                             }
1312*52da9a59SGnoCiYeH                             _ => {
1313*52da9a59SGnoCiYeH                                 // 不是特殊字节码,则表示控制字符 例如 ^C
1314*52da9a59SGnoCiYeH                                 if space < 2 {
1315*52da9a59SGnoCiYeH                                     break;
1316*52da9a59SGnoCiYeH                                 }
1317*52da9a59SGnoCiYeH 
1318*52da9a59SGnoCiYeH                                 if tty.put_char(tty.core(), b'^').is_err() {
1319*52da9a59SGnoCiYeH                                     tty.write(core, &[b'^'], 1)?;
1320*52da9a59SGnoCiYeH                                 }
1321*52da9a59SGnoCiYeH 
1322*52da9a59SGnoCiYeH                                 if tty.put_char(tty.core(), ch ^ 0o100).is_err() {
1323*52da9a59SGnoCiYeH                                     tty.write(core, &[ch ^ 0o100], 1)?;
1324*52da9a59SGnoCiYeH                                 }
1325*52da9a59SGnoCiYeH 
1326*52da9a59SGnoCiYeH                                 self.cursor_column += 2;
1327*52da9a59SGnoCiYeH                                 space -= 2;
1328*52da9a59SGnoCiYeH                                 tail += 2;
1329*52da9a59SGnoCiYeH                             }
1330*52da9a59SGnoCiYeH                         }
1331*52da9a59SGnoCiYeH                     }
1332*52da9a59SGnoCiYeH                 }
1333*52da9a59SGnoCiYeH             } else {
1334*52da9a59SGnoCiYeH                 if termios.output_mode.contains(OutputMode::OPOST) {
1335*52da9a59SGnoCiYeH                     let ret = self.do_output_char(tty.clone(), c, space);
1336*52da9a59SGnoCiYeH 
1337*52da9a59SGnoCiYeH                     if ret.is_err() {
1338*52da9a59SGnoCiYeH                         break;
1339*52da9a59SGnoCiYeH                     }
1340*52da9a59SGnoCiYeH                     space -= ret.unwrap();
1341*52da9a59SGnoCiYeH                 } else {
1342*52da9a59SGnoCiYeH                     if space == 0 {
1343*52da9a59SGnoCiYeH                         break;
1344*52da9a59SGnoCiYeH                     }
1345*52da9a59SGnoCiYeH 
1346*52da9a59SGnoCiYeH                     if tty.put_char(tty.core(), c).is_err() {
1347*52da9a59SGnoCiYeH                         tty.write(core, &[c], 1)?;
1348*52da9a59SGnoCiYeH                     }
1349*52da9a59SGnoCiYeH                     space -= 1;
1350*52da9a59SGnoCiYeH                 }
1351*52da9a59SGnoCiYeH                 tail += 1;
1352*52da9a59SGnoCiYeH             }
1353*52da9a59SGnoCiYeH         }
1354*52da9a59SGnoCiYeH 
1355*52da9a59SGnoCiYeH         // 如果回显缓冲区接近满(在下一次提交之前可能会发生回显溢出的情况),则丢弃足够的尾部数据以防止随后的溢出。
1356*52da9a59SGnoCiYeH         while self.echo_commit > tail && self.echo_commit - tail >= ECHO_DISCARD_WATERMARK {
1357*52da9a59SGnoCiYeH             if self.echo_buf[ntty_buf_mask(tail)] == EchoOperation::Start.to_u8() {
1358*52da9a59SGnoCiYeH                 if self.echo_buf[ntty_buf_mask(tail + 1)] == EchoOperation::EraseTab.to_u8() {
1359*52da9a59SGnoCiYeH                     tail += 3;
1360*52da9a59SGnoCiYeH                 } else {
1361*52da9a59SGnoCiYeH                     tail += 2;
1362*52da9a59SGnoCiYeH                 }
1363*52da9a59SGnoCiYeH             } else {
1364*52da9a59SGnoCiYeH                 tail += 1;
1365*52da9a59SGnoCiYeH             }
1366*52da9a59SGnoCiYeH         }
1367*52da9a59SGnoCiYeH 
1368*52da9a59SGnoCiYeH         self.echo_tail = tail;
1369*52da9a59SGnoCiYeH         return Ok(ospace - space);
1370*52da9a59SGnoCiYeH     }
1371*52da9a59SGnoCiYeH 
1372*52da9a59SGnoCiYeH     /// ## 处理输出字符(带有 OPOST 处理)
1373*52da9a59SGnoCiYeH     pub fn process_output(&mut self, tty: Arc<TtyCore>, c: u8) -> bool {
1374*52da9a59SGnoCiYeH         let space = tty.write_room(tty.core());
1375*52da9a59SGnoCiYeH 
1376*52da9a59SGnoCiYeH         if self.do_output_char(tty, c, space).is_err() {
1377*52da9a59SGnoCiYeH             return false;
1378*52da9a59SGnoCiYeH         }
1379*52da9a59SGnoCiYeH 
1380*52da9a59SGnoCiYeH         true
1381*52da9a59SGnoCiYeH     }
1382*52da9a59SGnoCiYeH 
1383*52da9a59SGnoCiYeH     // ## 设置带有 OPOST 处理的tty输出一个字符
1384*52da9a59SGnoCiYeH     pub fn do_output_char(
1385*52da9a59SGnoCiYeH         &mut self,
1386*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
1387*52da9a59SGnoCiYeH         c: u8,
1388*52da9a59SGnoCiYeH         space: usize,
1389*52da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
1390*52da9a59SGnoCiYeH         if space == 0 {
1391*52da9a59SGnoCiYeH             return Err(SystemError::ENOBUFS);
1392*52da9a59SGnoCiYeH         }
1393*52da9a59SGnoCiYeH 
1394*52da9a59SGnoCiYeH         let termios = tty.core().termios();
1395*52da9a59SGnoCiYeH         let core = tty.core();
1396*52da9a59SGnoCiYeH         let mut c = c;
1397*52da9a59SGnoCiYeH         if c as usize == 8 {
1398*52da9a59SGnoCiYeH             // 表示退格
1399*52da9a59SGnoCiYeH             if self.cursor_column > 0 {
1400*52da9a59SGnoCiYeH                 self.cursor_column -= 1;
1401*52da9a59SGnoCiYeH             }
1402*52da9a59SGnoCiYeH             if tty.put_char(tty.core(), c).is_err() {
1403*52da9a59SGnoCiYeH                 tty.write(core, &[c], 1)?;
1404*52da9a59SGnoCiYeH             }
1405*52da9a59SGnoCiYeH             return Ok(1);
1406*52da9a59SGnoCiYeH         }
1407*52da9a59SGnoCiYeH         match c as char {
1408*52da9a59SGnoCiYeH             '\n' => {
1409*52da9a59SGnoCiYeH                 if termios.output_mode.contains(OutputMode::ONLRET) {
1410*52da9a59SGnoCiYeH                     // 回车符
1411*52da9a59SGnoCiYeH                     self.cursor_column = 0;
1412*52da9a59SGnoCiYeH                 }
1413*52da9a59SGnoCiYeH                 if termios.output_mode.contains(OutputMode::ONLCR) {
1414*52da9a59SGnoCiYeH                     // 映射为“\r\n”
1415*52da9a59SGnoCiYeH                     if space < 2 {
1416*52da9a59SGnoCiYeH                         return Err(SystemError::ENOBUFS);
1417*52da9a59SGnoCiYeH                     }
1418*52da9a59SGnoCiYeH                     self.cursor_column = 0;
1419*52da9a59SGnoCiYeH                     self.canon_cursor_column = 0;
1420*52da9a59SGnoCiYeH 
1421*52da9a59SGnoCiYeH                     // 通过驱动写入
1422*52da9a59SGnoCiYeH                     tty.write(core, "\r\n".as_bytes(), 2)?;
1423*52da9a59SGnoCiYeH                     return Ok(2);
1424*52da9a59SGnoCiYeH                 }
1425*52da9a59SGnoCiYeH 
1426*52da9a59SGnoCiYeH                 self.canon_cursor_column = self.cursor_column;
1427*52da9a59SGnoCiYeH             }
1428*52da9a59SGnoCiYeH             '\r' => {
1429*52da9a59SGnoCiYeH                 if termios.output_mode.contains(OutputMode::ONOCR) && self.cursor_column == 0 {
1430*52da9a59SGnoCiYeH                     // 光标已经在第0列,则不输出回车符
1431*52da9a59SGnoCiYeH                     return Ok(0);
1432*52da9a59SGnoCiYeH                 }
1433*52da9a59SGnoCiYeH 
1434*52da9a59SGnoCiYeH                 if termios.output_mode.contains(OutputMode::OCRNL) {
1435*52da9a59SGnoCiYeH                     // 输出的\r映射为\n
1436*52da9a59SGnoCiYeH                     c = b'\n';
1437*52da9a59SGnoCiYeH                     if termios.output_mode.contains(OutputMode::ONLRET) {
1438*52da9a59SGnoCiYeH                         // \r映射为\n,但是保留\r特性
1439*52da9a59SGnoCiYeH                         self.cursor_column = 0;
1440*52da9a59SGnoCiYeH                         self.canon_cursor_column = 0;
1441*52da9a59SGnoCiYeH                     }
1442*52da9a59SGnoCiYeH                 } else {
1443*52da9a59SGnoCiYeH                     self.cursor_column = 0;
1444*52da9a59SGnoCiYeH                     self.canon_cursor_column = 0;
1445*52da9a59SGnoCiYeH                 }
1446*52da9a59SGnoCiYeH             }
1447*52da9a59SGnoCiYeH             '\t' => {
1448*52da9a59SGnoCiYeH                 // 计算输出一个\t需要的空间
1449*52da9a59SGnoCiYeH                 let spaces = 8 - (self.cursor_column & 7) as usize;
1450*52da9a59SGnoCiYeH                 if termios.output_mode.contains(OutputMode::TABDLY) {
1451*52da9a59SGnoCiYeH                     if OutputMode::TABDLY.bits() == OutputMode::XTABS.bits() {
1452*52da9a59SGnoCiYeH                         // 配置的tab选项是真正输出空格到驱动
1453*52da9a59SGnoCiYeH                         if space < spaces {
1454*52da9a59SGnoCiYeH                             // 空间不够
1455*52da9a59SGnoCiYeH                             return Err(SystemError::ENOBUFS);
1456*52da9a59SGnoCiYeH                         }
1457*52da9a59SGnoCiYeH                         self.cursor_column += spaces as u32;
1458*52da9a59SGnoCiYeH                         // 写入sapces个空格
1459*52da9a59SGnoCiYeH                         tty.write(core, "        ".as_bytes(), spaces)?;
1460*52da9a59SGnoCiYeH                         return Ok(spaces);
1461*52da9a59SGnoCiYeH                     }
1462*52da9a59SGnoCiYeH                 }
1463*52da9a59SGnoCiYeH                 self.cursor_column += spaces as u32;
1464*52da9a59SGnoCiYeH             }
1465*52da9a59SGnoCiYeH             _ => {
1466*52da9a59SGnoCiYeH                 // 判断是否为控制字符
1467*52da9a59SGnoCiYeH                 if !(c as char).is_control() {
1468*52da9a59SGnoCiYeH                     if termios.output_mode.contains(OutputMode::OLCUC) {
1469*52da9a59SGnoCiYeH                         c = c.to_ascii_uppercase();
1470*52da9a59SGnoCiYeH                     }
1471*52da9a59SGnoCiYeH 
1472*52da9a59SGnoCiYeH                     // 判断是否为utf8模式下的连续字符
1473*52da9a59SGnoCiYeH                     if !(termios.input_mode.contains(InputMode::IUTF8)
1474*52da9a59SGnoCiYeH                         && (c as usize) & 0xc0 == 0x80)
1475*52da9a59SGnoCiYeH                     {
1476*52da9a59SGnoCiYeH                         self.cursor_column += 1;
1477*52da9a59SGnoCiYeH                     }
1478*52da9a59SGnoCiYeH                 }
1479*52da9a59SGnoCiYeH             }
1480*52da9a59SGnoCiYeH         }
1481*52da9a59SGnoCiYeH 
1482*52da9a59SGnoCiYeH         if tty.put_char(tty.core(), c).is_err() {
1483*52da9a59SGnoCiYeH             tty.write(core, &[c], 1)?;
1484*52da9a59SGnoCiYeH         }
1485*52da9a59SGnoCiYeH         Ok(1)
1486*52da9a59SGnoCiYeH     }
1487*52da9a59SGnoCiYeH }
1488*52da9a59SGnoCiYeH 
1489*52da9a59SGnoCiYeH impl TtyLineDiscipline for NTtyLinediscipline {
1490*52da9a59SGnoCiYeH     fn open(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
1491*52da9a59SGnoCiYeH         // 反向绑定tty到disc
1492*52da9a59SGnoCiYeH         self.disc_data().tty = Some(Arc::downgrade(&tty));
1493*52da9a59SGnoCiYeH         // 特定的tty设备在这里可能需要取消端口节流
1494*52da9a59SGnoCiYeH         return self.set_termios(tty, None);
1495*52da9a59SGnoCiYeH     }
1496*52da9a59SGnoCiYeH 
1497*52da9a59SGnoCiYeH     fn close(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
1498*52da9a59SGnoCiYeH         todo!()
1499*52da9a59SGnoCiYeH     }
1500*52da9a59SGnoCiYeH 
1501*52da9a59SGnoCiYeH     /// ## 重置缓冲区的基本信息
1502*52da9a59SGnoCiYeH     fn flush_buffer(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
1503*52da9a59SGnoCiYeH         let core = tty.core();
1504*52da9a59SGnoCiYeH         let _ = core.termios();
1505*52da9a59SGnoCiYeH         let mut ldata = self.disc_data();
1506*52da9a59SGnoCiYeH         ldata.read_head = 0;
1507*52da9a59SGnoCiYeH         ldata.canon_head = 0;
1508*52da9a59SGnoCiYeH         ldata.read_tail = 0;
1509*52da9a59SGnoCiYeH         ldata.commit_head = 0;
1510*52da9a59SGnoCiYeH         ldata.line_start = 0;
1511*52da9a59SGnoCiYeH         ldata.erasing = false;
1512*52da9a59SGnoCiYeH         ldata.read_flags.set_all(false);
1513*52da9a59SGnoCiYeH         ldata.pushing = false;
1514*52da9a59SGnoCiYeH         ldata.lookahead_count = 0;
1515*52da9a59SGnoCiYeH 
1516*52da9a59SGnoCiYeH         // todo: kick worker?
1517*52da9a59SGnoCiYeH         // todo: packet mode?
1518*52da9a59SGnoCiYeH 
1519*52da9a59SGnoCiYeH         Ok(())
1520*52da9a59SGnoCiYeH     }
1521*52da9a59SGnoCiYeH 
1522*52da9a59SGnoCiYeH     fn read(
1523*52da9a59SGnoCiYeH         &self,
1524*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
1525*52da9a59SGnoCiYeH         buf: &mut [u8],
1526*52da9a59SGnoCiYeH         len: usize,
1527*52da9a59SGnoCiYeH         cookie: &mut bool,
1528*52da9a59SGnoCiYeH         _offset: usize,
1529*52da9a59SGnoCiYeH         mode: FileMode,
1530*52da9a59SGnoCiYeH     ) -> Result<usize, system_error::SystemError> {
1531*52da9a59SGnoCiYeH         let mut ldata;
1532*52da9a59SGnoCiYeH         if mode.contains(FileMode::O_NONBLOCK) {
1533*52da9a59SGnoCiYeH             let ret = self.disc_data_try_lock();
1534*52da9a59SGnoCiYeH             if ret.is_err() {
1535*52da9a59SGnoCiYeH                 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
1536*52da9a59SGnoCiYeH             }
1537*52da9a59SGnoCiYeH             ldata = ret.unwrap();
1538*52da9a59SGnoCiYeH         } else {
1539*52da9a59SGnoCiYeH             ldata = self.disc_data();
1540*52da9a59SGnoCiYeH         }
1541*52da9a59SGnoCiYeH         let core = tty.core();
1542*52da9a59SGnoCiYeH         let termios = core.termios();
1543*52da9a59SGnoCiYeH         let mut nr = len;
1544*52da9a59SGnoCiYeH 
1545*52da9a59SGnoCiYeH         let mut offset = 0;
1546*52da9a59SGnoCiYeH 
1547*52da9a59SGnoCiYeH         // 表示接着读
1548*52da9a59SGnoCiYeH         if *cookie {
1549*52da9a59SGnoCiYeH             // 规范且非拓展模式
1550*52da9a59SGnoCiYeH             if ldata.icanon && !termios.local_mode.contains(LocalMode::EXTPROC) {
1551*52da9a59SGnoCiYeH                 // 跳过EOF字符
1552*52da9a59SGnoCiYeH                 if len == 0 {
1553*52da9a59SGnoCiYeH                     ldata.canon_skip_eof();
1554*52da9a59SGnoCiYeH                 } else if ldata.canon_copy_from_read_buf(buf, &mut nr, &mut offset)? {
1555*52da9a59SGnoCiYeH                     return Ok(len - nr);
1556*52da9a59SGnoCiYeH                 }
1557*52da9a59SGnoCiYeH             } else {
1558*52da9a59SGnoCiYeH                 if ldata.canon_copy_from_read_buf(buf, &mut nr, &mut offset)? {
1559*52da9a59SGnoCiYeH                     return Ok(len - nr);
1560*52da9a59SGnoCiYeH                 }
1561*52da9a59SGnoCiYeH             }
1562*52da9a59SGnoCiYeH 
1563*52da9a59SGnoCiYeH             // 没有数据可读
1564*52da9a59SGnoCiYeH 
1565*52da9a59SGnoCiYeH             // todo: kick worker? or 关闭节流?
1566*52da9a59SGnoCiYeH 
1567*52da9a59SGnoCiYeH             *cookie = false;
1568*52da9a59SGnoCiYeH             return Ok(len - nr);
1569*52da9a59SGnoCiYeH         }
1570*52da9a59SGnoCiYeH 
1571*52da9a59SGnoCiYeH         drop(termios);
1572*52da9a59SGnoCiYeH 
1573*52da9a59SGnoCiYeH         TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTIN)?;
1574*52da9a59SGnoCiYeH 
1575*52da9a59SGnoCiYeH         let mut minimum: usize = 0;
1576*52da9a59SGnoCiYeH         if !ldata.icanon {
1577*52da9a59SGnoCiYeH             let core = tty.core();
1578*52da9a59SGnoCiYeH             let termios = core.termios();
1579*52da9a59SGnoCiYeH             minimum = termios.control_characters[ControlCharIndex::VMIN] as usize;
1580*52da9a59SGnoCiYeH             if minimum == 0 {
1581*52da9a59SGnoCiYeH                 minimum = 1;
1582*52da9a59SGnoCiYeH             }
1583*52da9a59SGnoCiYeH         }
1584*52da9a59SGnoCiYeH 
1585*52da9a59SGnoCiYeH         let mut ret: Result<usize, SystemError> = Ok(0);
1586*52da9a59SGnoCiYeH         // 记录读取前 的tail
1587*52da9a59SGnoCiYeH         let tail = ldata.read_tail;
1588*52da9a59SGnoCiYeH         drop(ldata);
1589*52da9a59SGnoCiYeH         while nr != 0 {
1590*52da9a59SGnoCiYeH             // todo: 处理packet模式
1591*52da9a59SGnoCiYeH             let mut ldata = self.disc_data();
1592*52da9a59SGnoCiYeH 
1593*52da9a59SGnoCiYeH             let core = tty.core();
1594*52da9a59SGnoCiYeH             if !ldata.input_available(core.termios(), false) {
1595*52da9a59SGnoCiYeH                 if core.flags().contains(TtyFlag::OTHER_CLOSED) {
1596*52da9a59SGnoCiYeH                     ret = Err(SystemError::EIO);
1597*52da9a59SGnoCiYeH                     break;
1598*52da9a59SGnoCiYeH                 }
1599*52da9a59SGnoCiYeH 
1600*52da9a59SGnoCiYeH                 if core.flags().contains(TtyFlag::HUPPED) || core.flags().contains(TtyFlag::HUPPING)
1601*52da9a59SGnoCiYeH                 {
1602*52da9a59SGnoCiYeH                     break;
1603*52da9a59SGnoCiYeH                 }
1604*52da9a59SGnoCiYeH 
1605*52da9a59SGnoCiYeH                 if mode.contains(FileMode::O_NONBLOCK)
1606*52da9a59SGnoCiYeH                     || core.flags().contains(TtyFlag::LDISC_CHANGING)
1607*52da9a59SGnoCiYeH                 {
1608*52da9a59SGnoCiYeH                     ret = Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
1609*52da9a59SGnoCiYeH                     break;
1610*52da9a59SGnoCiYeH                 }
1611*52da9a59SGnoCiYeH 
1612*52da9a59SGnoCiYeH                 if ProcessManager::current_pcb()
1613*52da9a59SGnoCiYeH                     .sig_info()
1614*52da9a59SGnoCiYeH                     .sig_pending()
1615*52da9a59SGnoCiYeH                     .has_pending()
1616*52da9a59SGnoCiYeH                 {
1617*52da9a59SGnoCiYeH                     ret = Err(SystemError::ERESTARTSYS);
1618*52da9a59SGnoCiYeH                     break;
1619*52da9a59SGnoCiYeH                 }
1620*52da9a59SGnoCiYeH 
1621*52da9a59SGnoCiYeH                 // 休眠一段时间
1622*52da9a59SGnoCiYeH                 // 获取到termios读锁,避免termios被更改导致行为异常
1623*52da9a59SGnoCiYeH                 // let termios = core.termios_preempt_enable();
1624*52da9a59SGnoCiYeH                 // let helper = WakeUpHelper::new(ProcessManager::current_pcb());
1625*52da9a59SGnoCiYeH                 // let wakeup_helper = Timer::new(helper, timeout);
1626*52da9a59SGnoCiYeH                 // wakeup_helper.activate();
1627*52da9a59SGnoCiYeH                 // drop(termios);
1628*52da9a59SGnoCiYeH                 drop(ldata);
1629*52da9a59SGnoCiYeH                 core.read_wq()
1630*52da9a59SGnoCiYeH                     .sleep((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64);
1631*52da9a59SGnoCiYeH                 continue;
1632*52da9a59SGnoCiYeH             }
1633*52da9a59SGnoCiYeH 
1634*52da9a59SGnoCiYeH             if ldata.icanon && !core.termios().local_mode.contains(LocalMode::EXTPROC) {
1635*52da9a59SGnoCiYeH                 if ldata.canon_copy_from_read_buf(buf, &mut nr, &mut offset)? {
1636*52da9a59SGnoCiYeH                     *cookie = true;
1637*52da9a59SGnoCiYeH                     offset += len - nr;
1638*52da9a59SGnoCiYeH                     return Ok(offset);
1639*52da9a59SGnoCiYeH                 }
1640*52da9a59SGnoCiYeH             } else {
1641*52da9a59SGnoCiYeH                 // 非标准模式
1642*52da9a59SGnoCiYeH                 // todo: 处理packet模式
1643*52da9a59SGnoCiYeH 
1644*52da9a59SGnoCiYeH                 // 拷贝数据
1645*52da9a59SGnoCiYeH                 if ldata.copy_from_read_buf(core.termios(), buf, &mut nr, &mut offset)?
1646*52da9a59SGnoCiYeH                     && offset >= minimum
1647*52da9a59SGnoCiYeH                 {
1648*52da9a59SGnoCiYeH                     *cookie = true;
1649*52da9a59SGnoCiYeH                     return Ok(offset);
1650*52da9a59SGnoCiYeH                 }
1651*52da9a59SGnoCiYeH             }
1652*52da9a59SGnoCiYeH 
1653*52da9a59SGnoCiYeH             if offset >= minimum {
1654*52da9a59SGnoCiYeH                 break;
1655*52da9a59SGnoCiYeH             }
1656*52da9a59SGnoCiYeH         }
1657*52da9a59SGnoCiYeH         let ldata = self.disc_data();
1658*52da9a59SGnoCiYeH         if tail != ldata.read_tail {
1659*52da9a59SGnoCiYeH             // todo: kick worker?
1660*52da9a59SGnoCiYeH         }
1661*52da9a59SGnoCiYeH 
1662*52da9a59SGnoCiYeH         if offset > 0 {
1663*52da9a59SGnoCiYeH             return Ok(offset);
1664*52da9a59SGnoCiYeH         }
1665*52da9a59SGnoCiYeH 
1666*52da9a59SGnoCiYeH         ret
1667*52da9a59SGnoCiYeH     }
1668*52da9a59SGnoCiYeH 
1669*52da9a59SGnoCiYeH     fn write(
1670*52da9a59SGnoCiYeH         &self,
1671*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
1672*52da9a59SGnoCiYeH         buf: &[u8],
1673*52da9a59SGnoCiYeH         len: usize,
1674*52da9a59SGnoCiYeH         mode: FileMode,
1675*52da9a59SGnoCiYeH     ) -> Result<usize, system_error::SystemError> {
1676*52da9a59SGnoCiYeH         let mut nr = len;
1677*52da9a59SGnoCiYeH         let mut ldata = self.disc_data();
1678*52da9a59SGnoCiYeH         let pcb = ProcessManager::current_pcb();
1679*52da9a59SGnoCiYeH         let binding = tty.clone();
1680*52da9a59SGnoCiYeH         let core = binding.core();
1681*52da9a59SGnoCiYeH         let termios = core.termios().clone();
1682*52da9a59SGnoCiYeH         if termios.local_mode.contains(LocalMode::TOSTOP) {
1683*52da9a59SGnoCiYeH             TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTOU)?;
1684*52da9a59SGnoCiYeH         }
1685*52da9a59SGnoCiYeH 
1686*52da9a59SGnoCiYeH         ldata.process_echoes(tty.clone());
1687*52da9a59SGnoCiYeH         // drop(ldata);
1688*52da9a59SGnoCiYeH         let mut offset = 0;
1689*52da9a59SGnoCiYeH         loop {
1690*52da9a59SGnoCiYeH             if pcb.sig_info().sig_pending().has_pending() {
1691*52da9a59SGnoCiYeH                 return Err(SystemError::ERESTARTSYS);
1692*52da9a59SGnoCiYeH             }
1693*52da9a59SGnoCiYeH             if core.flags().contains(TtyFlag::HUPPED) {
1694*52da9a59SGnoCiYeH                 return Err(SystemError::EIO);
1695*52da9a59SGnoCiYeH             }
1696*52da9a59SGnoCiYeH             if termios.output_mode.contains(OutputMode::OPOST) {
1697*52da9a59SGnoCiYeH                 while nr > 0 {
1698*52da9a59SGnoCiYeH                     // let mut ldata = self.disc_data();
1699*52da9a59SGnoCiYeH                     // 获得一次处理后的数量
1700*52da9a59SGnoCiYeH                     let ret = ldata.process_output_block(core, core.termios(), &buf[offset..], nr);
1701*52da9a59SGnoCiYeH                     let num = match ret {
1702*52da9a59SGnoCiYeH                         Ok(num) => num,
1703*52da9a59SGnoCiYeH                         Err(e) => {
1704*52da9a59SGnoCiYeH                             if e == SystemError::EAGAIN_OR_EWOULDBLOCK {
1705*52da9a59SGnoCiYeH                                 break;
1706*52da9a59SGnoCiYeH                             } else {
1707*52da9a59SGnoCiYeH                                 return Err(e);
1708*52da9a59SGnoCiYeH                             }
1709*52da9a59SGnoCiYeH                         }
1710*52da9a59SGnoCiYeH                     };
1711*52da9a59SGnoCiYeH 
1712*52da9a59SGnoCiYeH                     offset += num;
1713*52da9a59SGnoCiYeH                     nr -= num;
1714*52da9a59SGnoCiYeH 
1715*52da9a59SGnoCiYeH                     if nr == 0 {
1716*52da9a59SGnoCiYeH                         break;
1717*52da9a59SGnoCiYeH                     }
1718*52da9a59SGnoCiYeH 
1719*52da9a59SGnoCiYeH                     let c = buf[offset];
1720*52da9a59SGnoCiYeH                     if !ldata.process_output(tty.clone(), c) {
1721*52da9a59SGnoCiYeH                         break;
1722*52da9a59SGnoCiYeH                     }
1723*52da9a59SGnoCiYeH                     offset += 1;
1724*52da9a59SGnoCiYeH                     nr -= 1;
1725*52da9a59SGnoCiYeH                 }
1726*52da9a59SGnoCiYeH 
1727*52da9a59SGnoCiYeH                 let _ = tty.flush_chars(core);
1728*52da9a59SGnoCiYeH             } else {
1729*52da9a59SGnoCiYeH                 while nr > 0 {
1730*52da9a59SGnoCiYeH                     let write = tty.write(core, &buf[offset..], nr)?;
1731*52da9a59SGnoCiYeH                     if write == 0 {
1732*52da9a59SGnoCiYeH                         break;
1733*52da9a59SGnoCiYeH                     }
1734*52da9a59SGnoCiYeH                     offset += write;
1735*52da9a59SGnoCiYeH                     nr -= write;
1736*52da9a59SGnoCiYeH                 }
1737*52da9a59SGnoCiYeH             }
1738*52da9a59SGnoCiYeH 
1739*52da9a59SGnoCiYeH             if nr == 0 {
1740*52da9a59SGnoCiYeH                 break;
1741*52da9a59SGnoCiYeH             }
1742*52da9a59SGnoCiYeH 
1743*52da9a59SGnoCiYeH             if mode.contains(FileMode::O_NONBLOCK) || core.flags().contains(TtyFlag::LDISC_CHANGING)
1744*52da9a59SGnoCiYeH             {
1745*52da9a59SGnoCiYeH                 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
1746*52da9a59SGnoCiYeH             }
1747*52da9a59SGnoCiYeH 
1748*52da9a59SGnoCiYeH             // 到这里表明没位置可写了
1749*52da9a59SGnoCiYeH             // 休眠一段时间
1750*52da9a59SGnoCiYeH             // 获取到termios读锁,避免termios被更改导致行为异常
1751*52da9a59SGnoCiYeH             core.write_wq()
1752*52da9a59SGnoCiYeH                 .sleep(EPollEventType::EPOLLOUT.bits() as u64);
1753*52da9a59SGnoCiYeH         }
1754*52da9a59SGnoCiYeH 
1755*52da9a59SGnoCiYeH         Ok(offset)
1756*52da9a59SGnoCiYeH     }
1757*52da9a59SGnoCiYeH 
1758*52da9a59SGnoCiYeH     fn ioctl(
1759*52da9a59SGnoCiYeH         &self,
1760*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
1761*52da9a59SGnoCiYeH         cmd: u32,
1762*52da9a59SGnoCiYeH         arg: usize,
1763*52da9a59SGnoCiYeH     ) -> Result<usize, system_error::SystemError> {
1764*52da9a59SGnoCiYeH         match cmd {
1765*52da9a59SGnoCiYeH             TtyIoctlCmd::TIOCOUTQ => {
1766*52da9a59SGnoCiYeH                 let mut user_writer = UserBufferWriter::new(
1767*52da9a59SGnoCiYeH                     VirtAddr::new(arg).as_ptr::<i32>(),
1768*52da9a59SGnoCiYeH                     core::mem::size_of::<i32>(),
1769*52da9a59SGnoCiYeH                     true,
1770*52da9a59SGnoCiYeH                 )?;
1771*52da9a59SGnoCiYeH 
1772*52da9a59SGnoCiYeH                 let count = tty.chars_in_buffer();
1773*52da9a59SGnoCiYeH                 user_writer.copy_one_to_user::<i32>(&(count as i32), 0)?;
1774*52da9a59SGnoCiYeH                 return Ok(0);
1775*52da9a59SGnoCiYeH             }
1776*52da9a59SGnoCiYeH             TtyIoctlCmd::FIONREAD => {
1777*52da9a59SGnoCiYeH                 let ldata = self.disc_data();
1778*52da9a59SGnoCiYeH                 let termios = tty.core().termios();
1779*52da9a59SGnoCiYeH                 let retval;
1780*52da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::ICANON)
1781*52da9a59SGnoCiYeH                     && !termios.local_mode.contains(LocalMode::EXTPROC)
1782*52da9a59SGnoCiYeH                 {
1783*52da9a59SGnoCiYeH                     if ldata.canon_head == ldata.read_tail {
1784*52da9a59SGnoCiYeH                         retval = 0;
1785*52da9a59SGnoCiYeH                     } else {
1786*52da9a59SGnoCiYeH                         let head = ldata.canon_head;
1787*52da9a59SGnoCiYeH                         let mut tail = ldata.read_tail;
1788*52da9a59SGnoCiYeH                         let mut nr = head - tail;
1789*52da9a59SGnoCiYeH 
1790*52da9a59SGnoCiYeH                         while ntty_buf_mask(head) != ntty_buf_mask(tail) {
1791*52da9a59SGnoCiYeH                             if ldata.read_flags.get(ntty_buf_mask(tail)).unwrap()
1792*52da9a59SGnoCiYeH                                 && ldata.read_buf[ntty_buf_mask(tail)]
1793*52da9a59SGnoCiYeH                                     == ControlCharIndex::DISABLE_CHAR
1794*52da9a59SGnoCiYeH                             {
1795*52da9a59SGnoCiYeH                                 nr -= 1;
1796*52da9a59SGnoCiYeH                             }
1797*52da9a59SGnoCiYeH                             tail += 1;
1798*52da9a59SGnoCiYeH                         }
1799*52da9a59SGnoCiYeH 
1800*52da9a59SGnoCiYeH                         retval = nr;
1801*52da9a59SGnoCiYeH                     }
1802*52da9a59SGnoCiYeH                 } else {
1803*52da9a59SGnoCiYeH                     retval = ldata.read_cnt();
1804*52da9a59SGnoCiYeH                 }
1805*52da9a59SGnoCiYeH 
1806*52da9a59SGnoCiYeH                 let mut user_writer = UserBufferWriter::new(
1807*52da9a59SGnoCiYeH                     VirtAddr::new(arg).as_ptr::<i32>(),
1808*52da9a59SGnoCiYeH                     core::mem::size_of::<i32>(),
1809*52da9a59SGnoCiYeH                     true,
1810*52da9a59SGnoCiYeH                 )?;
1811*52da9a59SGnoCiYeH 
1812*52da9a59SGnoCiYeH                 user_writer.copy_one_to_user::<i32>(&(retval as i32), 0)?;
1813*52da9a59SGnoCiYeH                 return Ok(0);
1814*52da9a59SGnoCiYeH             }
1815*52da9a59SGnoCiYeH             _ => {
1816*52da9a59SGnoCiYeH                 return self.ioctl_helper(tty, cmd, arg);
1817*52da9a59SGnoCiYeH             }
1818*52da9a59SGnoCiYeH         }
1819*52da9a59SGnoCiYeH     }
1820*52da9a59SGnoCiYeH 
1821*52da9a59SGnoCiYeH     fn set_termios(
1822*52da9a59SGnoCiYeH         &self,
1823*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
1824*52da9a59SGnoCiYeH         old: Option<crate::driver::tty::termios::Termios>,
1825*52da9a59SGnoCiYeH     ) -> Result<(), system_error::SystemError> {
1826*52da9a59SGnoCiYeH         let core = tty.core();
1827*52da9a59SGnoCiYeH         let termios = core.termios();
1828*52da9a59SGnoCiYeH         let mut ldata = self.disc_data();
1829*52da9a59SGnoCiYeH         let contorl_chars = termios.control_characters;
1830*52da9a59SGnoCiYeH 
1831*52da9a59SGnoCiYeH         // 第一次设置或者规范模式 (ICANON) 或者扩展处理 (EXTPROC) 标志发生变化
1832*52da9a59SGnoCiYeH         if old.is_none()
1833*52da9a59SGnoCiYeH             || (old.is_some()
1834*52da9a59SGnoCiYeH                 && old
1835*52da9a59SGnoCiYeH                     .unwrap()
1836*52da9a59SGnoCiYeH                     .local_mode
1837*52da9a59SGnoCiYeH                     .bitxor(termios.local_mode)
1838*52da9a59SGnoCiYeH                     .contains(LocalMode::ICANON | LocalMode::EXTPROC))
1839*52da9a59SGnoCiYeH         {
1840*52da9a59SGnoCiYeH             // 重置read_flags
1841*52da9a59SGnoCiYeH             ldata.read_flags.set_all(false);
1842*52da9a59SGnoCiYeH 
1843*52da9a59SGnoCiYeH             ldata.line_start = ldata.read_tail;
1844*52da9a59SGnoCiYeH 
1845*52da9a59SGnoCiYeH             // 不是规范模式或者有可读数据
1846*52da9a59SGnoCiYeH             if !termios.local_mode.contains(LocalMode::ICANON) || ldata.read_cnt() != 0 {
1847*52da9a59SGnoCiYeH                 ldata.canon_head = ldata.read_tail;
1848*52da9a59SGnoCiYeH                 ldata.pushing = false;
1849*52da9a59SGnoCiYeH             } else {
1850*52da9a59SGnoCiYeH                 let read_head = ldata.read_head;
1851*52da9a59SGnoCiYeH                 ldata
1852*52da9a59SGnoCiYeH                     .read_flags
1853*52da9a59SGnoCiYeH                     .set((read_head - 1) & (NTTY_BUFSIZE - 1), true);
1854*52da9a59SGnoCiYeH                 ldata.canon_head = ldata.read_head;
1855*52da9a59SGnoCiYeH                 ldata.pushing = true;
1856*52da9a59SGnoCiYeH             }
1857*52da9a59SGnoCiYeH             ldata.commit_head = ldata.read_head;
1858*52da9a59SGnoCiYeH             ldata.erasing = false;
1859*52da9a59SGnoCiYeH             ldata.lnext = false;
1860*52da9a59SGnoCiYeH         }
1861*52da9a59SGnoCiYeH 
1862*52da9a59SGnoCiYeH         // 设置规范模式
1863*52da9a59SGnoCiYeH         if termios.local_mode.contains(LocalMode::ICANON) {
1864*52da9a59SGnoCiYeH             ldata.icanon = true;
1865*52da9a59SGnoCiYeH         }
1866*52da9a59SGnoCiYeH 
1867*52da9a59SGnoCiYeH         // 设置回显
1868*52da9a59SGnoCiYeH         if termios.local_mode.contains(LocalMode::ECHO) {
1869*52da9a59SGnoCiYeH             ldata.echo = true;
1870*52da9a59SGnoCiYeH         }
1871*52da9a59SGnoCiYeH 
1872*52da9a59SGnoCiYeH         if termios.input_mode.contains(InputMode::ISTRIP)
1873*52da9a59SGnoCiYeH             || termios.input_mode.contains(InputMode::IUCLC)
1874*52da9a59SGnoCiYeH             || termios.input_mode.contains(InputMode::IGNCR)
1875*52da9a59SGnoCiYeH             || termios.input_mode.contains(InputMode::IXON)
1876*52da9a59SGnoCiYeH             || termios.local_mode.contains(LocalMode::ISIG)
1877*52da9a59SGnoCiYeH             || termios.local_mode.contains(LocalMode::ECHO)
1878*52da9a59SGnoCiYeH             || termios.input_mode.contains(InputMode::PARMRK)
1879*52da9a59SGnoCiYeH         {
1880*52da9a59SGnoCiYeH             // 非原模式
1881*52da9a59SGnoCiYeH 
1882*52da9a59SGnoCiYeH             ldata.char_map.set_all(false);
1883*52da9a59SGnoCiYeH 
1884*52da9a59SGnoCiYeH             // 忽略回车符或者将回车映射为换行符
1885*52da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::IGNCR)
1886*52da9a59SGnoCiYeH                 || termios.input_mode.contains(InputMode::ICRNL)
1887*52da9a59SGnoCiYeH             {
1888*52da9a59SGnoCiYeH                 ldata.char_map.set('\r' as usize, true);
1889*52da9a59SGnoCiYeH             }
1890*52da9a59SGnoCiYeH 
1891*52da9a59SGnoCiYeH             // 将换行映射为回车
1892*52da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::INLCR) {
1893*52da9a59SGnoCiYeH                 ldata.char_map.set('\n' as usize, true);
1894*52da9a59SGnoCiYeH             }
1895*52da9a59SGnoCiYeH 
1896*52da9a59SGnoCiYeH             // 规范模式
1897*52da9a59SGnoCiYeH             if termios.local_mode.contains(LocalMode::ICANON) {
1898*52da9a59SGnoCiYeH                 ldata
1899*52da9a59SGnoCiYeH                     .char_map
1900*52da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VERASE] as usize, true);
1901*52da9a59SGnoCiYeH                 ldata
1902*52da9a59SGnoCiYeH                     .char_map
1903*52da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VKILL] as usize, true);
1904*52da9a59SGnoCiYeH                 ldata
1905*52da9a59SGnoCiYeH                     .char_map
1906*52da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VEOF] as usize, true);
1907*52da9a59SGnoCiYeH                 ldata.char_map.set('\n' as usize, true);
1908*52da9a59SGnoCiYeH                 ldata
1909*52da9a59SGnoCiYeH                     .char_map
1910*52da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VEOL] as usize, true);
1911*52da9a59SGnoCiYeH 
1912*52da9a59SGnoCiYeH                 if termios.local_mode.contains(LocalMode::IEXTEN) {
1913*52da9a59SGnoCiYeH                     ldata
1914*52da9a59SGnoCiYeH                         .char_map
1915*52da9a59SGnoCiYeH                         .set(contorl_chars[ControlCharIndex::VWERASE] as usize, true);
1916*52da9a59SGnoCiYeH                     ldata
1917*52da9a59SGnoCiYeH                         .char_map
1918*52da9a59SGnoCiYeH                         .set(contorl_chars[ControlCharIndex::VLNEXT] as usize, true);
1919*52da9a59SGnoCiYeH                     ldata
1920*52da9a59SGnoCiYeH                         .char_map
1921*52da9a59SGnoCiYeH                         .set(contorl_chars[ControlCharIndex::VEOL2] as usize, true);
1922*52da9a59SGnoCiYeH                     if termios.local_mode.contains(LocalMode::ECHO) {
1923*52da9a59SGnoCiYeH                         ldata
1924*52da9a59SGnoCiYeH                             .char_map
1925*52da9a59SGnoCiYeH                             .set(contorl_chars[ControlCharIndex::VREPRINT] as usize, true);
1926*52da9a59SGnoCiYeH                     }
1927*52da9a59SGnoCiYeH                 }
1928*52da9a59SGnoCiYeH             }
1929*52da9a59SGnoCiYeH 
1930*52da9a59SGnoCiYeH             // 软件流控制
1931*52da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::IXON) {
1932*52da9a59SGnoCiYeH                 ldata
1933*52da9a59SGnoCiYeH                     .char_map
1934*52da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VSTART] as usize, true);
1935*52da9a59SGnoCiYeH                 ldata
1936*52da9a59SGnoCiYeH                     .char_map
1937*52da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VSTOP] as usize, true);
1938*52da9a59SGnoCiYeH             }
1939*52da9a59SGnoCiYeH 
1940*52da9a59SGnoCiYeH             if termios.local_mode.contains(LocalMode::ISIG) {
1941*52da9a59SGnoCiYeH                 ldata
1942*52da9a59SGnoCiYeH                     .char_map
1943*52da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VINTR] as usize, true);
1944*52da9a59SGnoCiYeH                 ldata
1945*52da9a59SGnoCiYeH                     .char_map
1946*52da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VQUIT] as usize, true);
1947*52da9a59SGnoCiYeH                 ldata
1948*52da9a59SGnoCiYeH                     .char_map
1949*52da9a59SGnoCiYeH                     .set(contorl_chars[ControlCharIndex::VSUSP] as usize, true);
1950*52da9a59SGnoCiYeH             }
1951*52da9a59SGnoCiYeH 
1952*52da9a59SGnoCiYeH             ldata
1953*52da9a59SGnoCiYeH                 .char_map
1954*52da9a59SGnoCiYeH                 .set(ControlCharIndex::DISABLE_CHAR as usize, true);
1955*52da9a59SGnoCiYeH             ldata.raw = false;
1956*52da9a59SGnoCiYeH             ldata.real_raw = false;
1957*52da9a59SGnoCiYeH         } else {
1958*52da9a59SGnoCiYeH             // 原模式或real_raw
1959*52da9a59SGnoCiYeH             ldata.raw = true;
1960*52da9a59SGnoCiYeH 
1961*52da9a59SGnoCiYeH             if termios.input_mode.contains(InputMode::IGNBRK)
1962*52da9a59SGnoCiYeH                 || (!termios.input_mode.contains(InputMode::BRKINT)
1963*52da9a59SGnoCiYeH                     && !termios.input_mode.contains(InputMode::PARMRK))
1964*52da9a59SGnoCiYeH                     && (termios.input_mode.contains(InputMode::IGNPAR)
1965*52da9a59SGnoCiYeH                         || !termios.input_mode.contains(InputMode::INPCK))
1966*52da9a59SGnoCiYeH                     && (core
1967*52da9a59SGnoCiYeH                         .driver()
1968*52da9a59SGnoCiYeH                         .flags()
1969*52da9a59SGnoCiYeH                         .contains(TtyDriverFlag::TTY_DRIVER_REAL_RAW))
1970*52da9a59SGnoCiYeH             {
1971*52da9a59SGnoCiYeH                 ldata.real_raw = true;
1972*52da9a59SGnoCiYeH             } else {
1973*52da9a59SGnoCiYeH                 ldata.real_raw = false;
1974*52da9a59SGnoCiYeH             }
1975*52da9a59SGnoCiYeH         }
1976*52da9a59SGnoCiYeH 
1977*52da9a59SGnoCiYeH         // if !termios.input_mode.contains(InputMode::IXON)
1978*52da9a59SGnoCiYeH         //     && old.is_some()
1979*52da9a59SGnoCiYeH         //     && old.unwrap().input_mode.contains(InputMode::IXON) && !
1980*52da9a59SGnoCiYeH         // {}
1981*52da9a59SGnoCiYeH 
1982*52da9a59SGnoCiYeH         core.read_wq().wakeup_all();
1983*52da9a59SGnoCiYeH         core.write_wq().wakeup_all();
1984*52da9a59SGnoCiYeH         Ok(())
1985*52da9a59SGnoCiYeH     }
1986*52da9a59SGnoCiYeH 
1987*52da9a59SGnoCiYeH     fn poll(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
1988*52da9a59SGnoCiYeH         todo!()
1989*52da9a59SGnoCiYeH     }
1990*52da9a59SGnoCiYeH 
1991*52da9a59SGnoCiYeH     fn hangup(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
1992*52da9a59SGnoCiYeH         todo!()
1993*52da9a59SGnoCiYeH     }
1994*52da9a59SGnoCiYeH 
1995*52da9a59SGnoCiYeH     fn receive_buf(
1996*52da9a59SGnoCiYeH         &self,
1997*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
1998*52da9a59SGnoCiYeH         buf: &[u8],
1999*52da9a59SGnoCiYeH         flags: Option<&[u8]>,
2000*52da9a59SGnoCiYeH         count: usize,
2001*52da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
2002*52da9a59SGnoCiYeH         let mut ldata = self.disc_data();
2003*52da9a59SGnoCiYeH         ldata.receive_buf_common(tty, buf, flags, count, false)
2004*52da9a59SGnoCiYeH     }
2005*52da9a59SGnoCiYeH 
2006*52da9a59SGnoCiYeH     fn receive_buf2(
2007*52da9a59SGnoCiYeH         &self,
2008*52da9a59SGnoCiYeH         tty: Arc<TtyCore>,
2009*52da9a59SGnoCiYeH         buf: &[u8],
2010*52da9a59SGnoCiYeH         flags: Option<&[u8]>,
2011*52da9a59SGnoCiYeH         count: usize,
2012*52da9a59SGnoCiYeH     ) -> Result<usize, SystemError> {
2013*52da9a59SGnoCiYeH         let mut ldata = self.disc_data();
2014*52da9a59SGnoCiYeH         ldata.receive_buf_common(tty, buf, flags, count, true)
2015*52da9a59SGnoCiYeH     }
2016*52da9a59SGnoCiYeH }
2017