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