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