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