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