xref: /DragonOS/kernel/src/driver/tty/tty_ldisc/ntty.rs (revision 1ea2daad8121b77ed704e6d7c3a09f478147441d)
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 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 mut 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         ctrl_info.pgid = None;
795         ctrl_info.session = None;
796 
797         if !termios.local_mode.contains(LocalMode::NOFLSH) {
798             // 重置
799             self.echo_head = 0;
800             self.echo_tail = 0;
801             self.echo_mark = 0;
802             self.echo_commit = 0;
803 
804             let _ = tty.flush_buffer(tty.core());
805 
806             self.read_head = 0;
807             self.canon_head = 0;
808             self.read_tail = 0;
809             self.line_start = 0;
810 
811             self.erasing = false;
812             self.read_flags.set_all(false);
813             self.pushing = false;
814             self.lookahead_count = 0;
815 
816             if tty.core().link().is_some() {
817                 self.packet_mode_flush(tty.core());
818             }
819         }
820     }
821 
822     pub fn receive_char(&mut self, c: u8, tty: Arc<TtyCore>) {
823         let termios = tty.core().termios();
824 
825         if termios.local_mode.contains(LocalMode::ECHO) {
826             if self.erasing {
827                 self.add_echo_byte(b'/');
828                 self.erasing = false;
829             }
830 
831             if self.canon_head == self.read_head {
832                 self.add_echo_byte(EchoOperation::Start.to_u8());
833                 self.add_echo_byte(EchoOperation::SetCanonCol.to_u8());
834             }
835 
836             self.echo_char(c, &termios);
837             self.commit_echoes(tty.clone());
838         }
839 
840         if c == 0o377 && tty.core().termios().input_mode.contains(InputMode::PARMRK) {
841             self.add_read_byte(c);
842         }
843         self.add_read_byte(c);
844     }
845 
846     pub fn echo_char(&mut self, c: u8, termios: &RwLockReadGuard<Termios>) {
847         if c == EchoOperation::Start.to_u8() {
848             self.add_echo_byte(EchoOperation::Start.to_u8());
849             self.add_echo_byte(EchoOperation::Start.to_u8());
850         } else {
851             if termios.local_mode.contains(LocalMode::ECHOCTL)
852                 && (c as char).is_control()
853                 && c != b'\t'
854             {
855                 self.add_echo_byte(EchoOperation::Start.to_u8());
856             }
857             self.add_echo_byte(c);
858         }
859     }
860 
861     pub fn echo_char_raw(&mut self, c: u8) {
862         if c == EchoOperation::Start.to_u8() {
863             self.add_echo_byte(EchoOperation::Start.to_u8());
864             self.add_echo_byte(EchoOperation::Start.to_u8());
865         } else {
866             self.add_echo_byte(c);
867         }
868     }
869 
870     /// ## 提交echobuf里的数据显示
871     pub fn commit_echoes(&mut self, tty: Arc<TtyCore>) {
872         let head = self.echo_head;
873         self.echo_mark = head;
874         let old = self.echo_commit - self.echo_tail;
875 
876         // 需要echo的字符个数
877         let nr = head - self.echo_tail;
878 
879         if nr < ECHO_COMMIT_WATERMARK || nr % ECHO_BLOCK > old % ECHO_BLOCK {
880             return;
881         }
882 
883         self.echo_commit = head;
884         let echoed = self.echoes(tty.clone());
885 
886         if echoed.is_ok() && echoed.unwrap() > 0 {
887             tty.flush_chars(tty.core());
888         }
889     }
890 
891     pub fn add_echo_byte(&mut self, c: u8) {
892         self.echo_buf[ntty_buf_mask(self.echo_head)] = c;
893         self.echo_head += 1;
894     }
895 
896     pub fn add_read_byte(&mut self, c: u8) {
897         self.read_buf[ntty_buf_mask(self.read_head)] = c;
898         self.read_head += 1;
899     }
900 
901     /// ### 将read_buffer的部分值置0
902     ///
903     /// 只会在规范模式和禁用echo下执行
904     #[inline]
905     pub fn zero_buffer(&mut self, offset: usize, size: usize) {
906         let offset = offset & (NTTY_BUFSIZE - 1);
907         if self.icanon && !self.echo {
908             let n = offset + size;
909             if n > NTTY_BUFSIZE {
910                 for c in &mut self.read_buf[offset..NTTY_BUFSIZE] {
911                     *c = 0
912                 }
913 
914                 for c in &mut self.read_buf[0..(n - NTTY_BUFSIZE)] {
915                     *c = 0
916                 }
917             } else {
918                 for c in &mut self.read_buf[offset..n] {
919                     *c = 0
920                 }
921             };
922         }
923     }
924 
925     /// ## 从ntty中拷贝数据
926     ///
927     /// ### 参数
928     ///
929     /// ### to: 存储数据
930     /// ### tail: 读取尾
931     pub fn ntty_copy(
932         &mut self,
933         to: &mut [u8],
934         tail: usize,
935         n: &mut usize,
936     ) -> Result<(), SystemError> {
937         if to.len() < *n {
938             *n = to.len();
939             // return Err(SystemError::EINVAL);
940         }
941         if tail > NTTY_BUFSIZE {
942             return Err(SystemError::EINVAL);
943         }
944 
945         let size = NTTY_BUFSIZE - tail;
946 
947         if size < *n {
948             // 有一部分数据在头部,则先拷贝后面部分,再拷贝头部
949             // TODO: tty审计?
950             to[0..size].copy_from_slice(&self.read_buf[tail..(tail + size)]);
951             to[size..(*n)].copy_from_slice(&self.read_buf[0..(*n - size)]);
952         } else {
953             to[..*n].copy_from_slice(&self.read_buf[tail..(tail + *n)])
954         }
955 
956         self.zero_buffer(tail, *n);
957 
958         Ok(())
959     }
960 
961     /// ## 规范模式下跳过EOF
962     pub fn canon_skip_eof(&mut self) {
963         // 没有数据
964         if self.read_tail == self.canon_head {
965             return;
966         }
967 
968         let tail = self.read_tail & (NTTY_BUFSIZE - 1);
969 
970         // 查看read_flags是否读取位置为特殊字符
971         if !self.read_flags.get(tail).unwrap() {
972             return;
973         }
974 
975         // 确保读取位置是'\0'字符
976         if self.read_buf[tail] != ControlCharIndex::DISABLE_CHAR {
977             return;
978         }
979 
980         // 处理该字符,将read_flagsw该位清除
981         self.read_flags.set(tail, false);
982         // 读取位置+1,即跳过该字符不做处理
983         self.read_tail += 1;
984     }
985 
986     /// ## 在规范模式(canonical mode)下从读缓冲中复制一行
987     ///
988     /// 一次只拷贝一行
989     ///
990     /// ## 参数
991     /// ### dst: 存放数据
992     /// ### nr: 需要拷贝的数据大小
993     ///
994     /// ## 返回值
995     /// ### true: 表示一行未结束并且还有数据可读
996     /// ### false: 一行已结束或者没有数据可读
997     pub fn canon_copy_from_read_buf(
998         &mut self,
999         dst: &mut [u8],
1000         nr: &mut usize,
1001         offset: &mut usize,
1002     ) -> Result<bool, SystemError> {
1003         if *nr == 0 {
1004             return Ok(false);
1005         }
1006 
1007         let canon_head = self.canon_head;
1008 
1009         // 取得能够读到的字符数,即canon_head - self.read_tail和nr最小值
1010         let mut n = (*nr).min(canon_head - self.read_tail);
1011 
1012         // 获得读尾index
1013         let tail = self.read_tail & (NTTY_BUFSIZE - 1);
1014 
1015         // 避免越界,这个size才是实际读取大小
1016         let size = if tail + n > NTTY_BUFSIZE {
1017             NTTY_BUFSIZE
1018         } else {
1019             tail + n
1020         };
1021 
1022         // 找到eol的坐标
1023         let tmp = self.read_flags.next_index(tail);
1024         // 找到的话即为坐标,未找到的话即为NTTY_BUFSIZE
1025         let mut eol = if let Some(tmp) = tmp { tmp } else { size };
1026         if eol > size {
1027             eol = size
1028         }
1029 
1030         // 是否需要绕回缓冲区头部
1031         let more = n - (size - tail);
1032 
1033         // 是否找到eol
1034         let found = if eol == NTTY_BUFSIZE && more > 0 {
1035             // 需要返回头部
1036             let ret = self.read_flags.first_index();
1037             if let Some(tmp) = ret {
1038                 // 在头部范围内找到eol
1039                 if tmp < more {
1040                     eol = tmp;
1041                 }
1042             } else {
1043                 eol = more;
1044             }
1045             eol != more
1046         } else {
1047             // 不需要返回头部
1048             eol != size
1049         };
1050 
1051         n = eol - tail;
1052         if n > NTTY_BUFSIZE {
1053             // 减法溢出则加上BUFSIZE即可限制在0-NTTY_BUFSIZE内
1054             n += NTTY_BUFSIZE;
1055         }
1056 
1057         // 规范模式下实际扫描过的字符数,需要将eol计算在内
1058         let count = if found { n + 1 } else { n };
1059 
1060         // 表示这一行未结束
1061         if !found || self.read_at(eol) != ControlCharIndex::DISABLE_CHAR {
1062             n = count;
1063         }
1064 
1065         self.ntty_copy(&mut dst[*offset..], tail, &mut n)?;
1066         *nr -= n;
1067         *offset += n;
1068 
1069         if found {
1070             self.read_flags.set(eol, false);
1071         }
1072 
1073         self.read_tail += count;
1074 
1075         if found {
1076             if !self.pushing {
1077                 self.line_start = self.read_tail;
1078             } else {
1079                 self.pushing = false;
1080             }
1081 
1082             // todo: 审计?
1083             return Ok(false);
1084         }
1085 
1086         // 这里是表示没有找到eol,根据是否还有数据可读返回
1087         Ok(self.read_tail != canon_head)
1088     }
1089 
1090     /// ## 根据终端的模式和输入缓冲区中的数据量,判断是否可读字符
1091     pub fn input_available(&self, termios: RwLockReadGuard<Termios>, poll: bool) -> bool {
1092         // 计算最小字符数
1093         let amt = if poll
1094             && termios.control_characters[ControlCharIndex::VTIME] as u32 == 0
1095             && termios.control_characters[ControlCharIndex::VMIN] as u32 != 0
1096         {
1097             termios.control_characters[ControlCharIndex::VMIN] as usize
1098         } else {
1099             1
1100         };
1101 
1102         // 规范模式且非拓展
1103         if self.icanon && !termios.local_mode.contains(LocalMode::EXTPROC) {
1104             return self.canon_head != self.read_tail;
1105         } else {
1106             return (self.commit_head - self.read_tail) >= amt;
1107         }
1108     }
1109 
1110     /// ## 非规范模式下从read_buf读取数据
1111     ///
1112     /// ## 参数
1113     /// ### termios: tty对应的termioss读锁守卫
1114     /// ### dst: 存储读取数据
1115     /// ### nr: 读取长度
1116     ///
1117     /// ## 返回值
1118     /// ### true: 还有更多数据可读
1119     /// ### false: 无更多数据可读
1120     pub fn copy_from_read_buf(
1121         &mut self,
1122         termios: RwLockReadGuard<Termios>,
1123         dst: &mut [u8],
1124         nr: &mut usize,
1125         offset: &mut usize,
1126     ) -> Result<bool, SystemError> {
1127         let head = self.commit_head;
1128         let tail = self.read_tail & (NTTY_BUFSIZE - 1);
1129 
1130         // 计算出可读的字符数
1131         let mut n = (NTTY_BUFSIZE - tail).min(head - self.read_tail);
1132         n = n.min(*nr);
1133 
1134         if n > 0 {
1135             // 拷贝数据
1136             self.ntty_copy(&mut dst[*offset..], tail, &mut n)?;
1137             // todo:审计?
1138             self.read_tail += n;
1139 
1140             // 是否只读取了eof
1141             let eof =
1142                 n == 1 && self.read_buf[tail] == termios.control_characters[ControlCharIndex::VEOF];
1143 
1144             if termios.local_mode.contains(LocalMode::EXTPROC)
1145                 && self.icanon
1146                 && eof
1147                 && head == self.read_tail
1148             {
1149                 return Ok(false);
1150             }
1151 
1152             *nr -= n;
1153             *offset += n;
1154 
1155             return Ok(head != self.read_tail);
1156         }
1157 
1158         Ok(false)
1159     }
1160 
1161     /// ## 用于处理带有 OPOST(Output Post-processing)标志的输出块的函数
1162     /// OPOST 是 POSIX 终端驱动器标志之一,用于指定在写入终端设备之前对输出数据进行一些后期处理。
1163     pub fn process_output_block(
1164         &mut self,
1165         core: &TtyCoreData,
1166         termios: RwLockReadGuard<Termios>,
1167         buf: &[u8],
1168         nr: usize,
1169     ) -> Result<usize, SystemError> {
1170         let mut nr = nr;
1171         let tty = self.tty.upgrade().unwrap();
1172         let space = tty.write_room(tty.core());
1173 
1174         // 如果读取数量大于了可用空间,则取最小的为真正的写入数量
1175         if nr > space {
1176             nr = space
1177         }
1178 
1179         let mut cnt = 0;
1180         for (i, c) in buf.iter().enumerate().take(nr) {
1181             cnt = i;
1182             let c = *c;
1183             if c as usize == 8 {
1184                 // 表示退格
1185                 if self.cursor_column > 0 {
1186                     self.cursor_column -= 1;
1187                 }
1188                 continue;
1189             }
1190             match c as char {
1191                 '\n' => {
1192                     if termios.output_mode.contains(OutputMode::ONLRET) {
1193                         // 将回车映射为\n,即将\n换为回车
1194                         self.cursor_column = 0;
1195                     }
1196                     if termios.output_mode.contains(OutputMode::ONLCR) {
1197                         // 输出时将\n换为\r\n
1198                         break;
1199                     }
1200 
1201                     self.canon_cursor_column = self.cursor_column;
1202                 }
1203                 '\r' => {
1204                     if termios.output_mode.contains(OutputMode::ONOCR) && self.cursor_column == 0 {
1205                         // 光标已经在第0列,则不输出回车符
1206                         break;
1207                     }
1208 
1209                     if termios.output_mode.contains(OutputMode::OCRNL) {
1210                         break;
1211                     }
1212                     self.canon_cursor_column = self.cursor_column;
1213                 }
1214                 '\t' => {
1215                     break;
1216                 }
1217                 _ => {
1218                     // 判断是否为控制字符
1219                     if !(c as char).is_control() {
1220                         if termios.output_mode.contains(OutputMode::OLCUC) {
1221                             break;
1222                         }
1223 
1224                         // 判断是否为utf8模式下的连续字符
1225                         if !(termios.input_mode.contains(InputMode::IUTF8)
1226                             && (c as usize) & 0xc0 == 0x80)
1227                         {
1228                             self.cursor_column += 1;
1229                         }
1230                     }
1231                 }
1232             }
1233         }
1234 
1235         drop(termios);
1236         return tty.write(core, buf, cnt);
1237     }
1238 
1239     /// ## 处理回显
1240     pub fn process_echoes(&mut self, tty: Arc<TtyCore>) {
1241         if self.echo_mark == self.echo_tail {
1242             return;
1243         }
1244         self.echo_commit = self.echo_mark;
1245         let echoed = self.echoes(tty.clone());
1246 
1247         if echoed.is_ok() && echoed.unwrap() > 0 {
1248             tty.flush_chars(tty.core());
1249         }
1250     }
1251 
1252     #[inline(never)]
1253     pub fn echoes(&mut self, tty: Arc<TtyCore>) -> Result<usize, SystemError> {
1254         let mut space = tty.write_room(tty.core());
1255         let ospace = space;
1256         let termios = tty.core().termios();
1257         let core = tty.core();
1258         let mut tail = self.echo_tail;
1259 
1260         while ntty_buf_mask(self.echo_commit) != ntty_buf_mask(tail) {
1261             let c = self.echo_buf[ntty_buf_mask(tail)];
1262 
1263             if EchoOperation::from_u8(c) == EchoOperation::Start {
1264                 if ntty_buf_mask(self.echo_commit) == ntty_buf_mask(tail + 1) {
1265                     self.echo_tail = tail;
1266                     return Ok(ospace - space);
1267                 }
1268 
1269                 // 获取到start,之后取第一个作为op
1270                 let op = EchoOperation::from_u8(self.echo_buf[ntty_buf_mask(tail + 1)]);
1271 
1272                 match op {
1273                     EchoOperation::Start => {
1274                         if space == 0 {
1275                             break;
1276                         }
1277 
1278                         if tty
1279                             .put_char(tty.core(), EchoOperation::Start.to_u8())
1280                             .is_err()
1281                         {
1282                             tty.write(core, &[EchoOperation::Start.to_u8()], 1)?;
1283                         }
1284 
1285                         self.cursor_column += 1;
1286                         space -= 1;
1287                         tail += 2;
1288                     }
1289                     EchoOperation::MoveBackCol => {
1290                         if self.cursor_column > 0 {
1291                             self.cursor_column -= 1;
1292                         }
1293                         tail += 2;
1294                     }
1295                     EchoOperation::SetCanonCol => {
1296                         self.canon_cursor_column = self.cursor_column;
1297                         tail += 2;
1298                     }
1299                     EchoOperation::EraseTab => {
1300                         if ntty_buf_mask(self.echo_commit) == ntty_buf_mask(tail + 2) {
1301                             self.echo_tail = tail;
1302                             return Ok(ospace - space);
1303                         }
1304 
1305                         // 要擦除的制表符所占用的列数
1306                         let mut char_num = self.echo_buf[ntty_buf_mask(tail + 2)] as usize;
1307 
1308                         /*
1309                            如果 num_chars 的最高位(0x80)未设置,
1310                            表示这是从输入的起始位置而不是从先前的制表符开始计算的列数。
1311                            在这种情况下,将 num_chars 与 ldata->canon_column 相加,否则,列数就是正常的制表符列数。
1312                         */
1313                         if char_num & 0x80 == 0 {
1314                             char_num += self.canon_cursor_column as usize;
1315                         }
1316 
1317                         // 计算要回退的列数,即制表符宽度减去实际占用的列数
1318                         let mut num_bs = 8 - (char_num & 7);
1319                         if num_bs > space {
1320                             // 表示左边没有足够空间回退
1321                             break;
1322                         }
1323 
1324                         space -= num_bs;
1325                         while num_bs != 0 {
1326                             num_bs -= 1;
1327                             // 8 => '\b'
1328                             if tty.put_char(tty.core(), 8).is_err() {
1329                                 tty.write(core, &[8], 1)?;
1330                             }
1331 
1332                             if self.cursor_column > 0 {
1333                                 self.cursor_column -= 1;
1334                             }
1335                         }
1336 
1337                         // 已经读取了 tail tail+1 tail+2,所以这里偏移加3
1338                         tail += 3;
1339                     }
1340                     EchoOperation::Undefined(ch) => {
1341                         match ch {
1342                             8 => {
1343                                 if tty.put_char(tty.core(), 8).is_err() {
1344                                     tty.write(core, &[8], 1)?;
1345                                 }
1346                                 if tty.put_char(tty.core(), b' ').is_err() {
1347                                     tty.write(core, &[b' '], 1)?;
1348                                 }
1349                                 self.cursor_column -= 1;
1350                                 space -= 1;
1351                                 tail += 1;
1352                             }
1353                             _ => {
1354                                 // 不是特殊字节码,则表示控制字符 例如 ^C
1355                                 if space < 2 {
1356                                     break;
1357                                 }
1358 
1359                                 if tty.put_char(tty.core(), b'^').is_err() {
1360                                     tty.write(core, &[b'^'], 1)?;
1361                                 }
1362 
1363                                 if tty.put_char(tty.core(), ch ^ 0o100).is_err() {
1364                                     tty.write(core, &[ch ^ 0o100], 1)?;
1365                                 }
1366 
1367                                 self.cursor_column += 2;
1368                                 space -= 2;
1369                                 tail += 2;
1370                             }
1371                         }
1372                     }
1373                 }
1374             } else {
1375                 if termios.output_mode.contains(OutputMode::OPOST) {
1376                     let ret = self.do_output_char(tty.clone(), c, space);
1377 
1378                     if ret.is_err() {
1379                         break;
1380                     }
1381                     space -= ret.unwrap();
1382                 } else {
1383                     if space == 0 {
1384                         break;
1385                     }
1386 
1387                     if tty.put_char(tty.core(), c).is_err() {
1388                         tty.write(core, &[c], 1)?;
1389                     }
1390                     space -= 1;
1391                 }
1392                 tail += 1;
1393             }
1394         }
1395 
1396         // 如果回显缓冲区接近满(在下一次提交之前可能会发生回显溢出的情况),则丢弃足够的尾部数据以防止随后的溢出。
1397         while self.echo_commit > tail && self.echo_commit - tail >= ECHO_DISCARD_WATERMARK {
1398             if self.echo_buf[ntty_buf_mask(tail)] == EchoOperation::Start.to_u8() {
1399                 if self.echo_buf[ntty_buf_mask(tail + 1)] == EchoOperation::EraseTab.to_u8() {
1400                     tail += 3;
1401                 } else {
1402                     tail += 2;
1403                 }
1404             } else {
1405                 tail += 1;
1406             }
1407         }
1408 
1409         self.echo_tail = tail;
1410         return Ok(ospace - space);
1411     }
1412 
1413     /// ## 处理输出字符(带有 OPOST 处理)
1414     pub fn process_output(&mut self, tty: Arc<TtyCore>, c: u8) -> bool {
1415         let space = tty.write_room(tty.core());
1416 
1417         if self.do_output_char(tty, c, space).is_err() {
1418             return false;
1419         }
1420 
1421         true
1422     }
1423 
1424     // ## 设置带有 OPOST 处理的tty输出一个字符
1425     pub fn do_output_char(
1426         &mut self,
1427         tty: Arc<TtyCore>,
1428         c: u8,
1429         space: usize,
1430     ) -> Result<usize, SystemError> {
1431         if space == 0 {
1432             return Err(SystemError::ENOBUFS);
1433         }
1434 
1435         let termios = tty.core().termios();
1436         let core = tty.core();
1437         let mut c = c;
1438         if c as usize == 8 {
1439             // 表示退格
1440             if self.cursor_column > 0 {
1441                 self.cursor_column -= 1;
1442             }
1443             if tty.put_char(tty.core(), c).is_err() {
1444                 tty.write(core, &[c], 1)?;
1445             }
1446             return Ok(1);
1447         }
1448         match c as char {
1449             '\n' => {
1450                 if termios.output_mode.contains(OutputMode::ONLRET) {
1451                     // 回车符
1452                     self.cursor_column = 0;
1453                 }
1454                 if termios.output_mode.contains(OutputMode::ONLCR) {
1455                     // 映射为“\r\n”
1456                     if space < 2 {
1457                         return Err(SystemError::ENOBUFS);
1458                     }
1459                     self.cursor_column = 0;
1460                     self.canon_cursor_column = 0;
1461 
1462                     // 通过驱动写入
1463                     tty.write(core, "\r\n".as_bytes(), 2)?;
1464                     return Ok(2);
1465                 }
1466 
1467                 self.canon_cursor_column = self.cursor_column;
1468             }
1469             '\r' => {
1470                 if termios.output_mode.contains(OutputMode::ONOCR) && self.cursor_column == 0 {
1471                     // 光标已经在第0列,则不输出回车符
1472                     return Ok(0);
1473                 }
1474 
1475                 if termios.output_mode.contains(OutputMode::OCRNL) {
1476                     // 输出的\r映射为\n
1477                     c = b'\n';
1478                     if termios.output_mode.contains(OutputMode::ONLRET) {
1479                         // \r映射为\n,但是保留\r特性
1480                         self.cursor_column = 0;
1481                         self.canon_cursor_column = 0;
1482                     }
1483                 } else {
1484                     self.cursor_column = 0;
1485                     self.canon_cursor_column = 0;
1486                 }
1487             }
1488             '\t' => {
1489                 // 计算输出一个\t需要的空间
1490                 let spaces = 8 - (self.cursor_column & 7) as usize;
1491                 if termios.output_mode.contains(OutputMode::TABDLY)
1492                     && OutputMode::TABDLY.bits() == OutputMode::XTABS.bits()
1493                 {
1494                     // 配置的tab选项是真正输出空格到驱动
1495                     if space < spaces {
1496                         // 空间不够
1497                         return Err(SystemError::ENOBUFS);
1498                     }
1499                     self.cursor_column += spaces as u32;
1500                     // 写入sapces个空格
1501                     tty.write(core, "        ".as_bytes(), spaces)?;
1502                     return Ok(spaces);
1503                 }
1504                 self.cursor_column += spaces as u32;
1505             }
1506             _ => {
1507                 // 判断是否为控制字符
1508                 if !(c as char).is_control() {
1509                     if termios.output_mode.contains(OutputMode::OLCUC) {
1510                         c = c.to_ascii_uppercase();
1511                     }
1512 
1513                     // 判断是否为utf8模式下的连续字符
1514                     if !(termios.input_mode.contains(InputMode::IUTF8)
1515                         && (c as usize) & 0xc0 == 0x80)
1516                     {
1517                         self.cursor_column += 1;
1518                     }
1519                 }
1520             }
1521         }
1522 
1523         if tty.put_char(tty.core(), c).is_err() {
1524             tty.write(core, &[c], 1)?;
1525         }
1526         Ok(1)
1527     }
1528 
1529     fn packet_mode_flush(&self, tty: &TtyCoreData) {
1530         let link = tty.link().unwrap();
1531         if link.core().contorl_info_irqsave().packet {
1532             tty.contorl_info_irqsave()
1533                 .pktstatus
1534                 .insert(TtyPacketStatus::TIOCPKT_FLUSHREAD);
1535 
1536             link.core().read_wq().wakeup_all();
1537         }
1538     }
1539 }
1540 
1541 impl TtyLineDiscipline for NTtyLinediscipline {
1542     fn open(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
1543         // 反向绑定tty到disc
1544         self.disc_data().tty = Arc::downgrade(&tty);
1545         // 特定的tty设备在这里可能需要取消端口节流
1546         return self.set_termios(tty, None);
1547     }
1548 
1549     fn close(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
1550         todo!()
1551     }
1552 
1553     /// ## 重置缓冲区的基本信息
1554     fn flush_buffer(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
1555         let core = tty.core();
1556         let _ = core.termios();
1557         let mut ldata = self.disc_data();
1558         ldata.read_head = 0;
1559         ldata.canon_head = 0;
1560         ldata.read_tail = 0;
1561         ldata.commit_head = 0;
1562         ldata.line_start = 0;
1563         ldata.erasing = false;
1564         ldata.read_flags.set_all(false);
1565         ldata.pushing = false;
1566         ldata.lookahead_count = 0;
1567 
1568         // todo: kick worker?
1569         // packet mode?
1570         if core.link().is_some() {
1571             ldata.packet_mode_flush(core);
1572         }
1573 
1574         Ok(())
1575     }
1576 
1577     #[inline(never)]
1578     fn read(
1579         &self,
1580         tty: Arc<TtyCore>,
1581         buf: &mut [u8],
1582         len: usize,
1583         cookie: &mut bool,
1584         _offset: usize,
1585         mode: FileMode,
1586     ) -> Result<usize, system_error::SystemError> {
1587         let mut ldata;
1588         if mode.contains(FileMode::O_NONBLOCK) {
1589             let ret = self.disc_data_try_lock();
1590             if ret.is_err() {
1591                 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
1592             }
1593             ldata = ret.unwrap();
1594         } else {
1595             ldata = self.disc_data();
1596         }
1597         let core = tty.core();
1598         let termios = core.termios();
1599         let mut nr = len;
1600 
1601         let mut offset = 0;
1602 
1603         // 表示接着读
1604         if *cookie {
1605             // 规范且非拓展模式
1606             if ldata.icanon && !termios.local_mode.contains(LocalMode::EXTPROC) {
1607                 // 跳过EOF字符
1608                 if len == 0 {
1609                     ldata.canon_skip_eof();
1610                 } else if ldata.canon_copy_from_read_buf(buf, &mut nr, &mut offset)? {
1611                     return Ok(len - nr);
1612                 }
1613             } else if ldata.copy_from_read_buf(termios, buf, &mut nr, &mut offset)? {
1614                 return Ok(len - nr);
1615             }
1616 
1617             // 没有数据可读
1618 
1619             // todo: kick worker? or 关闭节流?
1620 
1621             *cookie = false;
1622             return Ok(len - nr);
1623         }
1624 
1625         drop(termios);
1626 
1627         TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTIN)?;
1628 
1629         let mut minimum: usize = 0;
1630         if !ldata.icanon {
1631             let core = tty.core();
1632             let termios = core.termios();
1633             minimum = termios.control_characters[ControlCharIndex::VMIN] as usize;
1634             if minimum == 0 {
1635                 minimum = 1;
1636             }
1637         }
1638 
1639         let packet = core.contorl_info_irqsave().packet;
1640         let mut ret: Result<usize, SystemError> = Ok(0);
1641         // 记录读取前 的tail
1642         let tail = ldata.read_tail;
1643         drop(ldata);
1644         while nr != 0 {
1645             // todo: 处理packet模式
1646             if packet {
1647                 let link = core.link().unwrap();
1648                 let link = link.core();
1649                 let mut ctrl = link.contorl_info_irqsave();
1650                 if !ctrl.pktstatus.is_empty() {
1651                     if offset != 0 {
1652                         break;
1653                     }
1654                     let cs = ctrl.pktstatus;
1655                     ctrl.pktstatus = TtyPacketStatus::empty();
1656 
1657                     buf[offset] = cs.bits();
1658                     offset += 1;
1659                     // nr -= 1;
1660                     break;
1661                 }
1662             }
1663 
1664             let mut ldata = self.disc_data();
1665 
1666             let core = tty.core();
1667             if !ldata.input_available(core.termios(), false) {
1668                 if core.flags().contains(TtyFlag::OTHER_CLOSED) {
1669                     ret = Err(SystemError::EIO);
1670                     break;
1671                 }
1672 
1673                 if core.flags().contains(TtyFlag::HUPPED) || core.flags().contains(TtyFlag::HUPPING)
1674                 {
1675                     break;
1676                 }
1677 
1678                 if mode.contains(FileMode::O_NONBLOCK)
1679                     || core.flags().contains(TtyFlag::LDISC_CHANGING)
1680                 {
1681                     ret = Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
1682                     break;
1683                 }
1684 
1685                 if ProcessManager::current_pcb()
1686                     .sig_info_irqsave()
1687                     .sig_pending()
1688                     .has_pending()
1689                 {
1690                     ret = Err(SystemError::ERESTARTSYS);
1691                     break;
1692                 }
1693 
1694                 // 休眠一段时间
1695                 // 获取到termios读锁,避免termios被更改导致行为异常
1696                 // let termios = core.termios_preempt_enable();
1697                 // let helper = WakeUpHelper::new(ProcessManager::current_pcb());
1698                 // let wakeup_helper = Timer::new(helper, timeout);
1699                 // wakeup_helper.activate();
1700                 // drop(termios);
1701                 drop(ldata);
1702                 core.read_wq()
1703                     .sleep((EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM).bits() as u64);
1704                 continue;
1705             }
1706 
1707             if ldata.icanon && !core.termios().local_mode.contains(LocalMode::EXTPROC) {
1708                 if ldata.canon_copy_from_read_buf(buf, &mut nr, &mut offset)? {
1709                     *cookie = true;
1710                     offset += len - nr;
1711                     return Ok(offset);
1712                 }
1713             } else {
1714                 // 非标准模式
1715                 // todo: 处理packet模式
1716                 if packet && offset == 0 {
1717                     buf[offset] = TtyPacketStatus::TIOCPKT_DATA.bits();
1718                     offset += 1;
1719                     nr -= 1;
1720                 }
1721                 // 拷贝数据
1722                 if ldata.copy_from_read_buf(core.termios(), buf, &mut nr, &mut offset)?
1723                     && offset >= minimum
1724                 {
1725                     *cookie = true;
1726                     return Ok(offset);
1727                 }
1728             }
1729 
1730             if offset >= minimum {
1731                 break;
1732             }
1733         }
1734         let ldata = self.disc_data();
1735         if tail != ldata.read_tail {
1736             // todo: kick worker?
1737         }
1738 
1739         if offset > 0 {
1740             return Ok(offset);
1741         }
1742 
1743         ret
1744     }
1745 
1746     #[inline(never)]
1747     fn write(
1748         &self,
1749         tty: Arc<TtyCore>,
1750         buf: &[u8],
1751         len: usize,
1752         mode: FileMode,
1753     ) -> Result<usize, system_error::SystemError> {
1754         let mut nr = len;
1755         let mut ldata = self.disc_data();
1756         let pcb = ProcessManager::current_pcb();
1757         let binding = tty.clone();
1758         let core = binding.core();
1759         let termios = *core.termios();
1760         if termios.local_mode.contains(LocalMode::TOSTOP) {
1761             TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTOU)?;
1762         }
1763 
1764         ldata.process_echoes(tty.clone());
1765         // drop(ldata);
1766         let mut offset = 0;
1767         loop {
1768             if pcb.sig_info_irqsave().sig_pending().has_pending() {
1769                 return Err(SystemError::ERESTARTSYS);
1770             }
1771             if core.flags().contains(TtyFlag::HUPPED) {
1772                 return Err(SystemError::EIO);
1773             }
1774             if termios.output_mode.contains(OutputMode::OPOST) {
1775                 while nr > 0 {
1776                     // let mut ldata = self.disc_data();
1777                     // 获得一次处理后的数量
1778                     let ret = ldata.process_output_block(core, core.termios(), &buf[offset..], nr);
1779                     let num = match ret {
1780                         Ok(num) => num,
1781                         Err(e) => {
1782                             if e == SystemError::EAGAIN_OR_EWOULDBLOCK {
1783                                 break;
1784                             } else {
1785                                 return Err(e);
1786                             }
1787                         }
1788                     };
1789 
1790                     offset += num;
1791                     nr -= num;
1792 
1793                     if nr == 0 {
1794                         break;
1795                     }
1796 
1797                     let c = buf[offset];
1798                     if !ldata.process_output(tty.clone(), c) {
1799                         break;
1800                     }
1801                     offset += 1;
1802                     nr -= 1;
1803                 }
1804 
1805                 tty.flush_chars(core);
1806             } else {
1807                 while nr > 0 {
1808                     let write = tty.write(core, &buf[offset..], nr)?;
1809                     if write == 0 {
1810                         break;
1811                     }
1812                     offset += write;
1813                     nr -= write;
1814                 }
1815             }
1816 
1817             if nr == 0 {
1818                 break;
1819             }
1820 
1821             if mode.contains(FileMode::O_NONBLOCK) || core.flags().contains(TtyFlag::LDISC_CHANGING)
1822             {
1823                 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
1824             }
1825 
1826             // 到这里表明没位置可写了
1827             // 休眠一段时间
1828             // 获取到termios读锁,避免termios被更改导致行为异常
1829             core.write_wq()
1830                 .sleep(EPollEventType::EPOLLOUT.bits() as u64);
1831         }
1832 
1833         Ok(offset)
1834     }
1835 
1836     fn ioctl(
1837         &self,
1838         tty: Arc<TtyCore>,
1839         cmd: u32,
1840         arg: usize,
1841     ) -> Result<usize, system_error::SystemError> {
1842         match cmd {
1843             TtyIoctlCmd::TIOCOUTQ => {
1844                 let mut user_writer = UserBufferWriter::new(
1845                     VirtAddr::new(arg).as_ptr::<i32>(),
1846                     core::mem::size_of::<i32>(),
1847                     true,
1848                 )?;
1849 
1850                 let count = tty.chars_in_buffer();
1851                 user_writer.copy_one_to_user::<i32>(&(count as i32), 0)?;
1852                 return Ok(0);
1853             }
1854             TtyIoctlCmd::FIONREAD => {
1855                 let ldata = self.disc_data();
1856                 let termios = tty.core().termios();
1857                 let retval;
1858                 if termios.local_mode.contains(LocalMode::ICANON)
1859                     && !termios.local_mode.contains(LocalMode::EXTPROC)
1860                 {
1861                     if ldata.canon_head == ldata.read_tail {
1862                         retval = 0;
1863                     } else {
1864                         let head = ldata.canon_head;
1865                         let mut tail = ldata.read_tail;
1866                         let mut nr = head - tail;
1867 
1868                         while ntty_buf_mask(head) != ntty_buf_mask(tail) {
1869                             if ldata.read_flags.get(ntty_buf_mask(tail)).unwrap()
1870                                 && ldata.read_buf[ntty_buf_mask(tail)]
1871                                     == ControlCharIndex::DISABLE_CHAR
1872                             {
1873                                 nr -= 1;
1874                             }
1875                             tail += 1;
1876                         }
1877 
1878                         retval = nr;
1879                     }
1880                 } else {
1881                     retval = ldata.read_cnt();
1882                 }
1883 
1884                 let mut user_writer = UserBufferWriter::new(
1885                     VirtAddr::new(arg).as_ptr::<i32>(),
1886                     core::mem::size_of::<i32>(),
1887                     true,
1888                 )?;
1889 
1890                 user_writer.copy_one_to_user::<i32>(&(retval as i32), 0)?;
1891                 return Ok(0);
1892             }
1893             _ => {
1894                 return self.ioctl_helper(tty, cmd, arg);
1895             }
1896         }
1897     }
1898 
1899     #[inline(never)]
1900     fn set_termios(
1901         &self,
1902         tty: Arc<TtyCore>,
1903         old: Option<crate::driver::tty::termios::Termios>,
1904     ) -> Result<(), system_error::SystemError> {
1905         let core = tty.core();
1906         let termios = core.termios();
1907         let mut ldata = self.disc_data();
1908         let contorl_chars = termios.control_characters;
1909 
1910         // 第一次设置或者规范模式 (ICANON) 或者扩展处理 (EXTPROC) 标志发生变化
1911         let mut spec_mode_changed = false;
1912         if let Some(old) = old {
1913             let local_mode = old.local_mode.bitxor(termios.local_mode);
1914             spec_mode_changed =
1915                 local_mode.contains(LocalMode::ICANON) || local_mode.contains(LocalMode::EXTPROC);
1916         }
1917         if old.is_none() || spec_mode_changed {
1918             // 重置read_flags
1919             ldata.read_flags.set_all(false);
1920 
1921             ldata.line_start = ldata.read_tail;
1922 
1923             // 不是规范模式或者有可读数据
1924             if !termios.local_mode.contains(LocalMode::ICANON) || ldata.read_cnt() != 0 {
1925                 ldata.canon_head = ldata.read_tail;
1926                 ldata.pushing = false;
1927             } else {
1928                 let read_head = ldata.read_head;
1929                 ldata
1930                     .read_flags
1931                     .set((read_head - 1) & (NTTY_BUFSIZE - 1), true);
1932                 ldata.canon_head = ldata.read_head;
1933                 ldata.pushing = true;
1934             }
1935             ldata.commit_head = ldata.read_head;
1936             ldata.erasing = false;
1937             ldata.lnext = false;
1938         }
1939 
1940         // 设置模式
1941         ldata.icanon = termios.local_mode.contains(LocalMode::ICANON);
1942 
1943         // 设置回显
1944         if termios.local_mode.contains(LocalMode::ECHO) {
1945             ldata.echo = true;
1946         }
1947 
1948         if termios.input_mode.contains(InputMode::ISTRIP)
1949             || termios.input_mode.contains(InputMode::IUCLC)
1950             || termios.input_mode.contains(InputMode::IGNCR)
1951             || termios.input_mode.contains(InputMode::IXON)
1952             || termios.local_mode.contains(LocalMode::ISIG)
1953             || termios.local_mode.contains(LocalMode::ECHO)
1954             || termios.input_mode.contains(InputMode::PARMRK)
1955         {
1956             // 非原模式
1957 
1958             ldata.char_map.set_all(false);
1959 
1960             // 忽略回车符或者将回车映射为换行符
1961             if termios.input_mode.contains(InputMode::IGNCR)
1962                 || termios.input_mode.contains(InputMode::ICRNL)
1963             {
1964                 ldata.char_map.set('\r' as usize, true);
1965             }
1966 
1967             // 将换行映射为回车
1968             if termios.input_mode.contains(InputMode::INLCR) {
1969                 ldata.char_map.set('\n' as usize, true);
1970             }
1971 
1972             // 规范模式
1973             if termios.local_mode.contains(LocalMode::ICANON) {
1974                 ldata
1975                     .char_map
1976                     .set(contorl_chars[ControlCharIndex::VERASE] as usize, true);
1977                 ldata
1978                     .char_map
1979                     .set(contorl_chars[ControlCharIndex::VKILL] as usize, true);
1980                 ldata
1981                     .char_map
1982                     .set(contorl_chars[ControlCharIndex::VEOF] as usize, true);
1983                 ldata.char_map.set('\n' as usize, true);
1984                 ldata
1985                     .char_map
1986                     .set(contorl_chars[ControlCharIndex::VEOL] as usize, true);
1987 
1988                 if termios.local_mode.contains(LocalMode::IEXTEN) {
1989                     ldata
1990                         .char_map
1991                         .set(contorl_chars[ControlCharIndex::VWERASE] as usize, true);
1992                     ldata
1993                         .char_map
1994                         .set(contorl_chars[ControlCharIndex::VLNEXT] as usize, true);
1995                     ldata
1996                         .char_map
1997                         .set(contorl_chars[ControlCharIndex::VEOL2] as usize, true);
1998                     if termios.local_mode.contains(LocalMode::ECHO) {
1999                         ldata
2000                             .char_map
2001                             .set(contorl_chars[ControlCharIndex::VREPRINT] as usize, true);
2002                     }
2003                 }
2004             }
2005 
2006             // 软件流控制
2007             if termios.input_mode.contains(InputMode::IXON) {
2008                 ldata
2009                     .char_map
2010                     .set(contorl_chars[ControlCharIndex::VSTART] as usize, true);
2011                 ldata
2012                     .char_map
2013                     .set(contorl_chars[ControlCharIndex::VSTOP] as usize, true);
2014             }
2015 
2016             if termios.local_mode.contains(LocalMode::ISIG) {
2017                 ldata
2018                     .char_map
2019                     .set(contorl_chars[ControlCharIndex::VINTR] as usize, true);
2020                 ldata
2021                     .char_map
2022                     .set(contorl_chars[ControlCharIndex::VQUIT] as usize, true);
2023                 ldata
2024                     .char_map
2025                     .set(contorl_chars[ControlCharIndex::VSUSP] as usize, true);
2026             }
2027 
2028             ldata
2029                 .char_map
2030                 .set(ControlCharIndex::DISABLE_CHAR as usize, true);
2031             ldata.raw = false;
2032             ldata.real_raw = false;
2033         } else {
2034             // 原模式或real_raw
2035             ldata.raw = true;
2036 
2037             ldata.real_raw = termios.input_mode.contains(InputMode::IGNBRK)
2038                 || (!termios.input_mode.contains(InputMode::BRKINT)
2039                     && !termios.input_mode.contains(InputMode::PARMRK))
2040                     && (termios.input_mode.contains(InputMode::IGNPAR)
2041                         || !termios.input_mode.contains(InputMode::INPCK))
2042                     && (core
2043                         .driver()
2044                         .flags()
2045                         .contains(TtyDriverFlag::TTY_DRIVER_REAL_RAW));
2046         }
2047 
2048         // if !termios.input_mode.contains(InputMode::IXON)
2049         //     && old.is_some()
2050         //     && old.unwrap().input_mode.contains(InputMode::IXON) && !
2051         // {}
2052 
2053         core.read_wq().wakeup_all();
2054         core.write_wq().wakeup_all();
2055         Ok(())
2056     }
2057 
2058     fn poll(&self, tty: Arc<TtyCore>) -> Result<usize, system_error::SystemError> {
2059         let core = tty.core();
2060         let ldata = self.disc_data();
2061 
2062         let mut event = EPollEventType::empty();
2063         if ldata.input_available(core.termios(), true) {
2064             event.insert(EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM)
2065         }
2066 
2067         if core.contorl_info_irqsave().packet {
2068             let link = core.link();
2069             if link.is_some()
2070                 && !link
2071                     .unwrap()
2072                     .core()
2073                     .contorl_info_irqsave()
2074                     .pktstatus
2075                     .is_empty()
2076             {
2077                 event.insert(
2078                     EPollEventType::EPOLLPRI
2079                         | EPollEventType::EPOLLIN
2080                         | EPollEventType::EPOLLRDNORM,
2081                 );
2082             }
2083         }
2084 
2085         if core.flags().contains(TtyFlag::OTHER_CLOSED) {
2086             event.insert(EPollEventType::EPOLLHUP);
2087         }
2088 
2089         if core.driver().driver_funcs().chars_in_buffer() < 256
2090             && core.driver().driver_funcs().write_room(core) > 0
2091         {
2092             event.insert(EPollEventType::EPOLLOUT | EPollEventType::EPOLLWRNORM);
2093         }
2094 
2095         Ok(event.bits() as usize)
2096     }
2097 
2098     fn hangup(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
2099         todo!()
2100     }
2101 
2102     fn receive_buf(
2103         &self,
2104         tty: Arc<TtyCore>,
2105         buf: &[u8],
2106         flags: Option<&[u8]>,
2107         count: usize,
2108     ) -> Result<usize, SystemError> {
2109         let mut ldata = self.disc_data();
2110         ldata.receive_buf_common(tty, buf, flags, count, false)
2111     }
2112 
2113     fn receive_buf2(
2114         &self,
2115         tty: Arc<TtyCore>,
2116         buf: &[u8],
2117         flags: Option<&[u8]>,
2118         count: usize,
2119     ) -> Result<usize, SystemError> {
2120         let mut ldata = self.disc_data();
2121         ldata.receive_buf_common(tty, buf, flags, count, true)
2122     }
2123 }
2124