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