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
ntty_buf_mask(idx: usize) -> usize34 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]
disc_data(&self) -> SpinLockGuard<NTtyData>45 pub fn disc_data(&self) -> SpinLockGuard<NTtyData> {
46 self.data.lock_irqsave()
47 }
48
49 #[inline]
disc_data_try_lock(&self) -> Result<SpinLockGuard<NTtyData>, SystemError>50 pub fn disc_data_try_lock(&self) -> Result<SpinLockGuard<NTtyData>, SystemError> {
51 self.data.try_lock_irqsave()
52 }
53
ioctl_helper(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError>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 {
new() -> Self129 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]
read_cnt(&self) -> usize160 pub fn read_cnt(&self) -> usize {
161 self.read_head - self.read_tail
162 }
163
164 #[inline]
read_at(&self, i: usize) -> u8165 pub fn read_at(&self, i: usize) -> u8 {
166 let i = i & (NTTY_BUFSIZE - 1);
167 self.read_buf[i]
168 }
169
170 /// ### 接收数据到NTTY
receive_buf_common( &mut self, tty: Arc<TtyCore>, buf: &[u8], flags: Option<&[u8]>, mut count: usize, flow: bool, ) -> Result<usize, SystemError>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
receive_buf( &mut self, tty: Arc<TtyCore>, buf: &[u8], flags: Option<&[u8]>, count: usize, )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
receive_buf_real_raw(&mut self, buf: &[u8], mut count: usize)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
receive_buf_raw(&mut self, buf: &[u8], flags: Option<&[u8]>, mut count: usize)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
flush_echoes(&mut self, tty: Arc<TtyCore>)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
receive_buf_standard( &mut self, tty: Arc<TtyCore>, buf: &[u8], flags: Option<&[u8]>, mut count: usize, lookahead_done: bool, )338 pub fn receive_buf_standard(
339 &mut self,
340 tty: Arc<TtyCore>,
341 buf: &[u8],
342 flags: Option<&[u8]>,
343 mut count: usize,
344 lookahead_done: bool,
345 ) {
346 let termios = tty.core().termios();
347 if flags.is_some() {
348 todo!("ntty recv buf flags todo");
349 }
350
351 let mut offset = 0;
352 while count > 0 {
353 if offset >= buf.len() {
354 break;
355 }
356 let mut c = buf[offset];
357 offset += 1;
358
359 if self.lnext {
360 // 将下一个字符当做字面值处理
361 self.lnext = false;
362 if termios.input_mode.contains(InputMode::ISTRIP) {
363 c &= 0x7f;
364 }
365
366 if termios.input_mode.contains(InputMode::IUCLC)
367 && termios.local_mode.contains(LocalMode::IEXTEN)
368 {
369 c = (c as char).to_ascii_lowercase() as u8;
370 self.receive_char(c, tty.clone())
371 }
372
373 continue;
374 }
375
376 if termios.input_mode.contains(InputMode::ISTRIP) {
377 c &= 0x7f;
378 }
379
380 if termios.input_mode.contains(InputMode::IUCLC)
381 && termios.local_mode.contains(LocalMode::IEXTEN)
382 {
383 c = (c as char).to_ascii_lowercase() as u8;
384 }
385
386 if termios.local_mode.contains(LocalMode::EXTPROC) {
387 self.add_read_byte(c);
388 continue;
389 }
390
391 if ((c as usize) < self.char_map.size()) && self.char_map.get(c as usize).unwrap() {
392 // 特殊字符
393 self.receive_special_char(c, tty.clone(), lookahead_done);
394 } else {
395 self.receive_char(c, tty.clone());
396 }
397
398 count -= 1;
399 }
400 }
401
402 #[inline(never)]
receive_special_char(&mut self, mut c: u8, tty: Arc<TtyCore>, lookahead_done: bool)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)]
eraser(&mut self, mut c: u8, termios: &RwLockReadGuard<Termios>)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
finish_erasing(&mut self)709 fn finish_erasing(&mut self) {
710 if self.erasing {
711 self.echo_char_raw(b'/');
712 self.erasing = false;
713 }
714 }
715
echo_erase_tab(&mut self, mut num: u8, after_tab: bool)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 /// 检测是否为多字节字符的后续字节
is_continuation(c: u8, termios: &RwLockReadGuard<Termios>) -> bool731 fn is_continuation(c: u8, termios: &RwLockReadGuard<Termios>) -> bool {
732 return termios.input_mode.contains(InputMode::IUTF8) && (c & 0xc0) == 0x80;
733 }
734
735 /// ## 该字符是否已经当做流控字符处理
is_flow_ctrl_char(&mut self, tty: Arc<TtyCore>, c: u8, lookahead_done: bool) -> bool736 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 /// ## 接收到信号字符时的处理
recv_sig_char( &mut self, tty: Arc<TtyCore>, termios: &RwLockReadGuard<Termios>, signal: Signal, c: u8, )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 /// ## 处理输入信号
input_signal( &mut self, tty: Arc<TtyCore>, termios: &RwLockReadGuard<Termios>, signal: Signal, )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
796 if !termios.local_mode.contains(LocalMode::NOFLSH) {
797 // 重置
798 self.echo_head = 0;
799 self.echo_tail = 0;
800 self.echo_mark = 0;
801 self.echo_commit = 0;
802
803 let _ = tty.flush_buffer(tty.core());
804
805 self.read_head = 0;
806 self.canon_head = 0;
807 self.read_tail = 0;
808 self.line_start = 0;
809
810 self.erasing = false;
811 self.read_flags.set_all(false);
812 self.pushing = false;
813 self.lookahead_count = 0;
814
815 if tty.core().link().is_some() {
816 self.packet_mode_flush(tty.core());
817 }
818 }
819 }
820
receive_char(&mut self, c: u8, tty: Arc<TtyCore>)821 pub fn receive_char(&mut self, c: u8, tty: Arc<TtyCore>) {
822 let termios = tty.core().termios();
823
824 if termios.local_mode.contains(LocalMode::ECHO) {
825 if self.erasing {
826 self.add_echo_byte(b'/');
827 self.erasing = false;
828 }
829
830 if self.canon_head == self.read_head {
831 self.add_echo_byte(EchoOperation::Start.to_u8());
832 self.add_echo_byte(EchoOperation::SetCanonCol.to_u8());
833 }
834
835 self.echo_char(c, &termios);
836 self.commit_echoes(tty.clone());
837 }
838
839 if c == 0o377 && tty.core().termios().input_mode.contains(InputMode::PARMRK) {
840 self.add_read_byte(c);
841 }
842 self.add_read_byte(c);
843 }
844
echo_char(&mut self, c: u8, termios: &RwLockReadGuard<Termios>)845 pub fn echo_char(&mut self, c: u8, termios: &RwLockReadGuard<Termios>) {
846 if c == EchoOperation::Start.to_u8() {
847 self.add_echo_byte(EchoOperation::Start.to_u8());
848 self.add_echo_byte(EchoOperation::Start.to_u8());
849 } else {
850 if termios.local_mode.contains(LocalMode::ECHOCTL)
851 && (c as char).is_control()
852 && c != b'\t'
853 {
854 self.add_echo_byte(EchoOperation::Start.to_u8());
855 }
856 self.add_echo_byte(c);
857 }
858 }
859
echo_char_raw(&mut self, c: u8)860 pub fn echo_char_raw(&mut self, c: u8) {
861 if c == EchoOperation::Start.to_u8() {
862 self.add_echo_byte(EchoOperation::Start.to_u8());
863 self.add_echo_byte(EchoOperation::Start.to_u8());
864 } else {
865 self.add_echo_byte(c);
866 }
867 }
868
869 /// ## 提交echobuf里的数据显示
commit_echoes(&mut self, tty: Arc<TtyCore>)870 pub fn commit_echoes(&mut self, tty: Arc<TtyCore>) {
871 let head = self.echo_head;
872 self.echo_mark = head;
873 let old = self.echo_commit - self.echo_tail;
874
875 // 需要echo的字符个数
876 let nr = head - self.echo_tail;
877
878 if nr < ECHO_COMMIT_WATERMARK || nr % ECHO_BLOCK > old % ECHO_BLOCK {
879 return;
880 }
881
882 self.echo_commit = head;
883 let echoed = self.echoes(tty.clone());
884
885 if echoed.is_ok() && echoed.unwrap() > 0 {
886 tty.flush_chars(tty.core());
887 }
888 }
889
add_echo_byte(&mut self, c: u8)890 pub fn add_echo_byte(&mut self, c: u8) {
891 self.echo_buf[ntty_buf_mask(self.echo_head)] = c;
892 self.echo_head += 1;
893 }
894
add_read_byte(&mut self, c: u8)895 pub fn add_read_byte(&mut self, c: u8) {
896 self.read_buf[ntty_buf_mask(self.read_head)] = c;
897 self.read_head += 1;
898 }
899
900 /// ### 将read_buffer的部分值置0
901 ///
902 /// 只会在规范模式和禁用echo下执行
903 #[inline]
zero_buffer(&mut self, offset: usize, size: usize)904 pub fn zero_buffer(&mut self, offset: usize, size: usize) {
905 let offset = offset & (NTTY_BUFSIZE - 1);
906 if self.icanon && !self.echo {
907 let n = offset + size;
908 if n > NTTY_BUFSIZE {
909 for c in &mut self.read_buf[offset..NTTY_BUFSIZE] {
910 *c = 0
911 }
912
913 for c in &mut self.read_buf[0..(n - NTTY_BUFSIZE)] {
914 *c = 0
915 }
916 } else {
917 for c in &mut self.read_buf[offset..n] {
918 *c = 0
919 }
920 };
921 }
922 }
923
924 /// ## 从ntty中拷贝数据
925 ///
926 /// ### 参数
927 ///
928 /// ### to: 存储数据
929 /// ### tail: 读取尾
ntty_copy( &mut self, to: &mut [u8], tail: usize, n: &mut usize, ) -> Result<(), SystemError>930 pub fn ntty_copy(
931 &mut self,
932 to: &mut [u8],
933 tail: usize,
934 n: &mut usize,
935 ) -> Result<(), SystemError> {
936 if to.len() < *n {
937 *n = to.len();
938 // return Err(SystemError::EINVAL);
939 }
940 if tail > NTTY_BUFSIZE {
941 return Err(SystemError::EINVAL);
942 }
943
944 let size = NTTY_BUFSIZE - tail;
945
946 if size < *n {
947 // 有一部分数据在头部,则先拷贝后面部分,再拷贝头部
948 // TODO: tty审计?
949 to[0..size].copy_from_slice(&self.read_buf[tail..(tail + size)]);
950 to[size..(*n)].copy_from_slice(&self.read_buf[0..(*n - size)]);
951 } else {
952 to[..*n].copy_from_slice(&self.read_buf[tail..(tail + *n)])
953 }
954
955 self.zero_buffer(tail, *n);
956
957 Ok(())
958 }
959
960 /// ## 规范模式下跳过EOF
canon_skip_eof(&mut self)961 pub fn canon_skip_eof(&mut self) {
962 // 没有数据
963 if self.read_tail == self.canon_head {
964 return;
965 }
966
967 let tail = self.read_tail & (NTTY_BUFSIZE - 1);
968
969 // 查看read_flags是否读取位置为特殊字符
970 if !self.read_flags.get(tail).unwrap() {
971 return;
972 }
973
974 // 确保读取位置是'\0'字符
975 if self.read_buf[tail] != ControlCharIndex::DISABLE_CHAR {
976 return;
977 }
978
979 // 处理该字符,将read_flagsw该位清除
980 self.read_flags.set(tail, false);
981 // 读取位置+1,即跳过该字符不做处理
982 self.read_tail += 1;
983 }
984
985 /// ## 在规范模式(canonical mode)下从读缓冲中复制一行
986 ///
987 /// 一次只拷贝一行
988 ///
989 /// ## 参数
990 /// ### dst: 存放数据
991 /// ### nr: 需要拷贝的数据大小
992 ///
993 /// ## 返回值
994 /// ### true: 表示一行未结束并且还有数据可读
995 /// ### false: 一行已结束或者没有数据可读
canon_copy_from_read_buf( &mut self, dst: &mut [u8], nr: &mut usize, offset: &mut usize, ) -> Result<bool, SystemError>996 pub fn canon_copy_from_read_buf(
997 &mut self,
998 dst: &mut [u8],
999 nr: &mut usize,
1000 offset: &mut usize,
1001 ) -> Result<bool, SystemError> {
1002 if *nr == 0 {
1003 return Ok(false);
1004 }
1005
1006 let canon_head = self.canon_head;
1007
1008 // 取得能够读到的字符数,即canon_head - self.read_tail和nr最小值
1009 let mut n = (*nr).min(canon_head - self.read_tail);
1010
1011 // 获得读尾index
1012 let tail = self.read_tail & (NTTY_BUFSIZE - 1);
1013
1014 // 避免越界,这个size才是实际读取大小
1015 let size = if tail + n > NTTY_BUFSIZE {
1016 NTTY_BUFSIZE
1017 } else {
1018 tail + n
1019 };
1020
1021 // 找到eol的坐标
1022 let tmp = self.read_flags.next_index(tail);
1023 // 找到的话即为坐标,未找到的话即为NTTY_BUFSIZE
1024 let mut eol = if let Some(tmp) = tmp { tmp } else { size };
1025 if eol > size {
1026 eol = size
1027 }
1028
1029 // 是否需要绕回缓冲区头部
1030 let more = n - (size - tail);
1031
1032 // 是否找到eol
1033 let found = if eol == NTTY_BUFSIZE && more > 0 {
1034 // 需要返回头部
1035 let ret = self.read_flags.first_index();
1036 if let Some(tmp) = ret {
1037 // 在头部范围内找到eol
1038 if tmp < more {
1039 eol = tmp;
1040 }
1041 } else {
1042 eol = more;
1043 }
1044 eol != more
1045 } else {
1046 // 不需要返回头部
1047 eol != size
1048 };
1049
1050 n = eol - tail;
1051 if n > NTTY_BUFSIZE {
1052 // 减法溢出则加上BUFSIZE即可限制在0-NTTY_BUFSIZE内
1053 n += NTTY_BUFSIZE;
1054 }
1055
1056 // 规范模式下实际扫描过的字符数,需要将eol计算在内
1057 let count = if found { n + 1 } else { n };
1058
1059 // 表示这一行未结束
1060 if !found || self.read_at(eol) != ControlCharIndex::DISABLE_CHAR {
1061 n = count;
1062 }
1063
1064 self.ntty_copy(&mut dst[*offset..], tail, &mut n)?;
1065 *nr -= n;
1066 *offset += n;
1067
1068 if found {
1069 self.read_flags.set(eol, false);
1070 }
1071
1072 self.read_tail += count;
1073
1074 if found {
1075 if !self.pushing {
1076 self.line_start = self.read_tail;
1077 } else {
1078 self.pushing = false;
1079 }
1080
1081 // todo: 审计?
1082 return Ok(false);
1083 }
1084
1085 // 这里是表示没有找到eol,根据是否还有数据可读返回
1086 Ok(self.read_tail != canon_head)
1087 }
1088
1089 /// ## 根据终端的模式和输入缓冲区中的数据量,判断是否可读字符
input_available(&self, termios: RwLockReadGuard<Termios>, poll: bool) -> bool1090 pub fn input_available(&self, termios: RwLockReadGuard<Termios>, poll: bool) -> bool {
1091 // 计算最小字符数
1092 let amt = if poll
1093 && termios.control_characters[ControlCharIndex::VTIME] as u32 == 0
1094 && termios.control_characters[ControlCharIndex::VMIN] as u32 != 0
1095 {
1096 termios.control_characters[ControlCharIndex::VMIN] as usize
1097 } else {
1098 1
1099 };
1100
1101 // 规范模式且非拓展
1102 if self.icanon && !termios.local_mode.contains(LocalMode::EXTPROC) {
1103 return self.canon_head != self.read_tail;
1104 } else {
1105 return (self.commit_head - self.read_tail) >= amt;
1106 }
1107 }
1108
1109 /// ## 非规范模式下从read_buf读取数据
1110 ///
1111 /// ## 参数
1112 /// ### termios: tty对应的termioss读锁守卫
1113 /// ### dst: 存储读取数据
1114 /// ### nr: 读取长度
1115 ///
1116 /// ## 返回值
1117 /// ### true: 还有更多数据可读
1118 /// ### false: 无更多数据可读
copy_from_read_buf( &mut self, termios: RwLockReadGuard<Termios>, dst: &mut [u8], nr: &mut usize, offset: &mut usize, ) -> Result<bool, SystemError>1119 pub fn copy_from_read_buf(
1120 &mut self,
1121 termios: RwLockReadGuard<Termios>,
1122 dst: &mut [u8],
1123 nr: &mut usize,
1124 offset: &mut usize,
1125 ) -> Result<bool, SystemError> {
1126 let head = self.commit_head;
1127 let tail = self.read_tail & (NTTY_BUFSIZE - 1);
1128
1129 // 计算出可读的字符数
1130 let mut n = (NTTY_BUFSIZE - tail).min(head - self.read_tail);
1131 n = n.min(*nr);
1132
1133 if n > 0 {
1134 // 拷贝数据
1135 self.ntty_copy(&mut dst[*offset..], tail, &mut n)?;
1136 // todo:审计?
1137 self.read_tail += n;
1138
1139 // 是否只读取了eof
1140 let eof =
1141 n == 1 && self.read_buf[tail] == termios.control_characters[ControlCharIndex::VEOF];
1142
1143 if termios.local_mode.contains(LocalMode::EXTPROC)
1144 && self.icanon
1145 && eof
1146 && head == self.read_tail
1147 {
1148 return Ok(false);
1149 }
1150
1151 *nr -= n;
1152 *offset += n;
1153
1154 return Ok(head != self.read_tail);
1155 }
1156
1157 Ok(false)
1158 }
1159
1160 /// ## 用于处理带有 OPOST(Output Post-processing)标志的输出块的函数
1161 /// OPOST 是 POSIX 终端驱动器标志之一,用于指定在写入终端设备之前对输出数据进行一些后期处理。
process_output_block( &mut self, core: &TtyCoreData, termios: RwLockReadGuard<Termios>, buf: &[u8], nr: usize, ) -> Result<usize, SystemError>1162 pub fn process_output_block(
1163 &mut self,
1164 core: &TtyCoreData,
1165 termios: RwLockReadGuard<Termios>,
1166 buf: &[u8],
1167 nr: usize,
1168 ) -> Result<usize, SystemError> {
1169 let mut nr = nr;
1170 let tty = self.tty.upgrade().unwrap();
1171 let space = tty.write_room(tty.core());
1172
1173 // 如果读取数量大于了可用空间,则取最小的为真正的写入数量
1174 if nr > space {
1175 nr = space
1176 }
1177
1178 let mut cnt = 0;
1179 for (i, c) in buf.iter().enumerate().take(nr) {
1180 cnt = i;
1181 let c = *c;
1182 if c as usize == 8 {
1183 // 表示退格
1184 if self.cursor_column > 0 {
1185 self.cursor_column -= 1;
1186 }
1187 continue;
1188 }
1189 match c as char {
1190 '\n' => {
1191 if termios.output_mode.contains(OutputMode::ONLRET) {
1192 // 将回车映射为\n,即将\n换为回车
1193 self.cursor_column = 0;
1194 }
1195 if termios.output_mode.contains(OutputMode::ONLCR) {
1196 // 输出时将\n换为\r\n
1197 break;
1198 }
1199
1200 self.canon_cursor_column = self.cursor_column;
1201 }
1202 '\r' => {
1203 if termios.output_mode.contains(OutputMode::ONOCR) && self.cursor_column == 0 {
1204 // 光标已经在第0列,则不输出回车符
1205 break;
1206 }
1207
1208 if termios.output_mode.contains(OutputMode::OCRNL) {
1209 break;
1210 }
1211 self.cursor_column = 0;
1212 self.canon_cursor_column = 0;
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 /// ## 处理回显
process_echoes(&mut self, tty: Arc<TtyCore>)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)]
echoes(&mut self, tty: Arc<TtyCore>) -> Result<usize, SystemError>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 处理)
process_output(&mut self, tty: Arc<TtyCore>, c: u8) -> bool1414 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输出一个字符
do_output_char( &mut self, tty: Arc<TtyCore>, c: u8, space: usize, ) -> Result<usize, SystemError>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
packet_mode_flush(&self, tty: &TtyCoreData)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 {
open(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError>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
close(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError>1549 fn close(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
1550 todo!()
1551 }
1552
1553 /// ## 重置缓冲区的基本信息
flush_buffer(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError>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)]
read( &self, tty: Arc<TtyCore>, buf: &mut [u8], len: usize, cookie: &mut bool, _offset: usize, mode: FileMode, ) -> Result<usize, system_error::SystemError>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)]
write( &self, tty: Arc<TtyCore>, buf: &[u8], len: usize, mode: FileMode, ) -> Result<usize, system_error::SystemError>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
ioctl( &self, tty: Arc<TtyCore>, cmd: u32, arg: usize, ) -> Result<usize, system_error::SystemError>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)]
set_termios( &self, tty: Arc<TtyCore>, old: Option<crate::driver::tty::termios::Termios>, ) -> Result<(), system_error::SystemError>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
poll(&self, tty: Arc<TtyCore>) -> Result<usize, system_error::SystemError>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
hangup(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError>2098 fn hangup(&self, _tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
2099 todo!()
2100 }
2101
receive_buf( &self, tty: Arc<TtyCore>, buf: &[u8], flags: Option<&[u8]>, count: usize, ) -> Result<usize, SystemError>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
receive_buf2( &self, tty: Arc<TtyCore>, buf: &[u8], flags: Option<&[u8]>, count: usize, ) -> Result<usize, SystemError>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