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