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