From 7014c94f85e1ecc95dbee3998550d43cb12033d6 Mon Sep 17 00:00:00 2001 From: GnoCiYeH Date: Tue, 9 Apr 2024 00:50:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84pty=EF=BC=8C=E7=9B=AE?= =?UTF-8?q?=E5=89=8Dpty=E8=83=BD=E5=A4=9F=E6=94=AF=E6=8C=81ssh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/src/driver/tty/pty/unix98pty.rs | 74 +++++++++++++++++-- kernel/src/driver/tty/termios.rs | 2 +- kernel/src/driver/tty/tty_core.rs | 27 ++++++- kernel/src/driver/tty/tty_device.rs | 23 +++++- kernel/src/driver/tty/tty_driver.rs | 6 +- kernel/src/driver/tty/tty_ldisc/ntty.rs | 8 +- kernel/src/driver/tty/virtual_terminal/mod.rs | 8 ++ kernel/src/filesystem/vfs/file.rs | 5 -- kernel/src/filesystem/vfs/syscall.rs | 4 + 9 files changed, 136 insertions(+), 21 deletions(-) diff --git a/kernel/src/driver/tty/pty/unix98pty.rs b/kernel/src/driver/tty/pty/unix98pty.rs index 1c8929d91..99bbab7bb 100644 --- a/kernel/src/driver/tty/pty/unix98pty.rs +++ b/kernel/src/driver/tty/pty/unix98pty.rs @@ -3,7 +3,7 @@ use system_error::SystemError; use crate::{ driver::tty::{ - termios::Termios, + termios::{ControlCharIndex, ControlMode, InputMode, LocalMode, Termios}, tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd, TtyPacketStatus}, tty_device::TtyFilePrivateData, tty_driver::{TtyDriver, TtyDriverPrivateData, TtyDriverSubType, TtyOperation}, @@ -76,7 +76,7 @@ impl TtyOperation for Unix98PtyDriverInner { fn ioctl(&self, tty: Arc, cmd: u32, arg: usize) -> Result<(), SystemError> { let core = tty.core(); if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtyMaster { - return Err(SystemError::ENOSYS); + return Err(SystemError::ENOIOCTLCMD); } match cmd { @@ -104,12 +104,58 @@ impl TtyOperation for Unix98PtyDriverInner { } } - fn set_termios(&self, tty: Arc, _old_termios: Termios) -> Result<(), SystemError> { + fn set_termios(&self, tty: Arc, old_termios: Termios) -> Result<(), SystemError> { let core = tty.core(); if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave { return Err(SystemError::ENOSYS); } - todo!() + + let core = tty.core(); + if let Some(link) = core.link() { + let link = link.core(); + if link.contorl_info_irqsave().packet { + let curr_termios = *core.termios(); + let extproc = old_termios.local_mode.contains(LocalMode::EXTPROC) + | curr_termios.local_mode.contains(LocalMode::EXTPROC); + + let old_flow = old_termios.input_mode.contains(InputMode::IXON) + && old_termios.control_characters[ControlCharIndex::VSTOP] == 0o023 + && old_termios.control_characters[ControlCharIndex::VSTART] == 0o021; + + let new_flow = curr_termios.input_mode.contains(InputMode::IXON) + && curr_termios.control_characters[ControlCharIndex::VSTOP] == 0o023 + && curr_termios.control_characters[ControlCharIndex::VSTART] == 0o021; + + if old_flow != new_flow || extproc { + let mut ctrl = core.contorl_info_irqsave(); + if old_flow != new_flow { + ctrl.pktstatus.remove( + TtyPacketStatus::TIOCPKT_DOSTOP | TtyPacketStatus::TIOCPKT_NOSTOP, + ); + + if new_flow { + ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_DOSTOP); + } else { + ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_NOSTOP); + } + } + + if extproc { + ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_IOCTL); + } + + link.read_wq().wakeup_all(); + } + } + } + let mut termois = core.termios_write(); + termois + .control_mode + .remove(ControlMode::CSIZE | ControlMode::PARENB); + termois + .control_mode + .insert(ControlMode::CS8 | ControlMode::CREAD); + Ok(()) } fn start(&self, core: &TtyCoreData) -> Result<(), SystemError> { @@ -171,8 +217,8 @@ impl TtyOperation for Unix98PtyDriverInner { fn close(&self, tty: Arc) -> Result<(), SystemError> { let driver = tty.core().driver(); - driver.ttys().remove(&tty.core().index()); if tty.core().driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave { + driver.ttys().remove(&tty.core().index()); let pts_root_inode = ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?; let _ = pts_root_inode.unlink(&tty.core().index().to_string()); @@ -180,6 +226,24 @@ impl TtyOperation for Unix98PtyDriverInner { Ok(()) } + + fn resize( + &self, + tty: Arc, + winsize: crate::driver::tty::termios::WindowSize, + ) -> Result<(), SystemError> { + let core = tty.core(); + if *core.window_size() == winsize { + return Ok(()); + } + + // TODO:向进程发送SIGWINCH信号 + + *core.window_size_write() = winsize; + *core.link().unwrap().core().window_size_write() = winsize; + + Ok(()) + } } pub fn ptmx_open( diff --git a/kernel/src/driver/tty/termios.rs b/kernel/src/driver/tty/termios.rs index 8490e68d5..8ba0c44d6 100644 --- a/kernel/src/driver/tty/termios.rs +++ b/kernel/src/driver/tty/termios.rs @@ -2,7 +2,7 @@ use super::tty_ldisc::LineDisciplineType; /// ## 窗口大小 #[repr(C)] -#[derive(Debug, Default, Clone, Copy)] +#[derive(Debug, Default, Clone, Copy, PartialEq)] pub struct WindowSize { /// 行 pub row: u16, diff --git a/kernel/src/driver/tty/tty_core.rs b/kernel/src/driver/tty/tty_core.rs index 7bc00af12..ecd7ee0c1 100644 --- a/kernel/src/driver/tty/tty_core.rs +++ b/kernel/src/driver/tty/tty_core.rs @@ -12,7 +12,7 @@ use alloc::{ use system_error::SystemError; use crate::{ - driver::serial::serial8250::send_to_default_serial8250_port, + driver::{serial::serial8250::send_to_default_serial8250_port, tty::pty::ptm_driver}, libs::{ rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard}, spinlock::{SpinLock, SpinLockGuard}, @@ -42,6 +42,14 @@ pub struct TtyCore { line_discipline: Arc, } +impl Drop for TtyCore { + fn drop(&mut self) { + if self.core.driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave { + ptm_driver().ttys().remove(&self.core().index); + } + } +} + impl TtyCore { pub fn new(driver: Arc, index: usize) -> Arc { let name = driver.tty_line_name(index); @@ -232,7 +240,9 @@ impl TtyCore { let tmp = termios.control_mode; termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB; + drop(termios); let ret = tty.set_termios(tty.clone(), old_termios); + let mut termios = tty.core().termios_write(); if ret.is_err() { termios.control_mode &= ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL; termios.control_mode |= old_termios.control_mode @@ -247,6 +257,12 @@ impl TtyCore { Ok(()) } + + pub fn tty_do_resize(&self, windowsize: WindowSize) -> Result<(), SystemError> { + // TODO: 向前台进程发送信号 + *self.core.window_size_write() = windowsize; + Ok(()) + } } #[derive(Debug, Default)] @@ -394,6 +410,11 @@ impl TtyCoreData { self.window_size.read() } + #[inline] + pub fn window_size_write(&self) -> RwLockWriteGuard { + self.window_size.write() + } + #[inline] pub fn is_closing(&self) -> bool { self.closing.load(core::sync::atomic::Ordering::SeqCst) @@ -511,6 +532,10 @@ impl TtyOperation for TtyCore { fn close(&self, tty: Arc) -> Result<(), SystemError> { self.core().tty_driver.driver_funcs().close(tty) } + + fn resize(&self, tty: Arc, winsize: WindowSize) -> Result<(), SystemError> { + self.core.tty_driver.driver_funcs().resize(tty, winsize) + } } bitflags! { diff --git a/kernel/src/driver/tty/tty_device.rs b/kernel/src/driver/tty/tty_device.rs index 197424010..e2458607c 100644 --- a/kernel/src/driver/tty/tty_device.rs +++ b/kernel/src/driver/tty/tty_device.rs @@ -134,10 +134,10 @@ impl IndexNode for TtyDevice { mut data: SpinLockGuard, mode: &crate::filesystem::vfs::file::FileMode, ) -> Result<(), SystemError> { + if let FilePrivateData::Tty(_) = &*data { + return Ok(()); + } if self.tty_type == TtyType::Pty(PtyType::Ptm) { - if let FilePrivateData::Tty(_) = &*data { - return Ok(()); - } return ptmx_open(data, mode); } let dev_num = self.metadata()?.raw_dev; @@ -360,6 +360,23 @@ impl IndexNode for TtyDevice { } return Ok(0); } + TtyIoctlCmd::TIOCSWINSZ => { + let reader = UserBufferReader::new( + arg as *const (), + core::mem::size_of::(), + true, + )?; + + let user_winsize = reader.read_one_from_user::(0)?; + + let ret = tty.resize(tty.clone(), *user_winsize); + + if ret != Err(SystemError::ENOSYS) { + return ret.map(|_| 0); + } else { + return tty.tty_do_resize(*user_winsize).map(|_| 0); + } + } _ => match TtyJobCtrlManager::job_ctrl_ioctl(tty.clone(), cmd, arg) { Ok(_) => { return Ok(0); diff --git a/kernel/src/driver/tty/tty_driver.rs b/kernel/src/driver/tty/tty_driver.rs index 5a6b40669..532250678 100644 --- a/kernel/src/driver/tty/tty_driver.rs +++ b/kernel/src/driver/tty/tty_driver.rs @@ -27,7 +27,7 @@ use crate::{ }; use super::{ - termios::Termios, + termios::{Termios, WindowSize}, tty_core::{TtyCore, TtyCoreData}, tty_ldisc::TtyLdiscManager, tty_port::{DefaultTtyPort, TtyPort}, @@ -273,7 +273,7 @@ impl TtyDriver { tty.set_port(ports[core.index()].clone()); } - TtyLdiscManager::ldisc_setup(tty.clone(), None)?; + TtyLdiscManager::ldisc_setup(tty.clone(), tty.core().link())?; Ok(tty) } @@ -445,6 +445,8 @@ pub trait TtyOperation: Sync + Send + Debug { } fn close(&self, tty: Arc) -> Result<(), SystemError>; + + fn resize(&self, _tty: Arc, _winsize: WindowSize) -> Result<(), SystemError>; } #[allow(dead_code)] diff --git a/kernel/src/driver/tty/tty_ldisc/ntty.rs b/kernel/src/driver/tty/tty_ldisc/ntty.rs index fc644abc0..9253a0e50 100644 --- a/kernel/src/driver/tty/tty_ldisc/ntty.rs +++ b/kernel/src/driver/tty/tty_ldisc/ntty.rs @@ -122,7 +122,7 @@ pub struct NTtyData { read_flags: StaticBitmap, char_map: StaticBitmap<256>, - tty: Option>, + tty: Weak, } impl NTtyData { @@ -151,7 +151,7 @@ impl NTtyData { echo_buf: [0; NTTY_BUFSIZE], read_flags: StaticBitmap::new(), char_map: StaticBitmap::new(), - tty: None, + tty: Weak::default(), no_room: false, } } @@ -1168,7 +1168,7 @@ impl NTtyData { nr: usize, ) -> Result { let mut nr = nr; - let tty = self.tty.clone().unwrap().upgrade().unwrap(); + let tty = self.tty.upgrade().unwrap(); let space = tty.write_room(tty.core()); // 如果读取数量大于了可用空间,则取最小的为真正的写入数量 @@ -1541,7 +1541,7 @@ impl NTtyData { impl TtyLineDiscipline for NTtyLinediscipline { fn open(&self, tty: Arc) -> Result<(), system_error::SystemError> { // 反向绑定tty到disc - self.disc_data().tty = Some(Arc::downgrade(&tty)); + self.disc_data().tty = Arc::downgrade(&tty); // 特定的tty设备在这里可能需要取消端口节流 return self.set_termios(tty, None); } diff --git a/kernel/src/driver/tty/virtual_terminal/mod.rs b/kernel/src/driver/tty/virtual_terminal/mod.rs index 51501e0d5..5a77aef05 100644 --- a/kernel/src/driver/tty/virtual_terminal/mod.rs +++ b/kernel/src/driver/tty/virtual_terminal/mod.rs @@ -242,6 +242,14 @@ impl TtyOperation for TtyConsoleDriverInner { fn close(&self, _tty: Arc) -> Result<(), SystemError> { Ok(()) } + + fn resize( + &self, + _tty: Arc, + _winsize: super::termios::WindowSize, + ) -> Result<(), SystemError> { + todo!() + } } #[derive(Debug, Clone)] diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 00760e52e..e7681c592 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -634,11 +634,6 @@ impl FileDescriptorVec { /// /// - `fd` 文件描述符序号 pub fn drop_fd(&mut self, fd: i32) -> Result<(), SystemError> { - // 判断文件描述符的数字是否超过限制 - if !FileDescriptorVec::validate_fd(fd) { - return Err(SystemError::EBADF); - } - self.get_file_by_fd(fd).ok_or(SystemError::EBADF)?; // 把文件描述符数组对应位置设置为空 diff --git a/kernel/src/filesystem/vfs/syscall.rs b/kernel/src/filesystem/vfs/syscall.rs index 0226eda72..12a7e2f33 100644 --- a/kernel/src/filesystem/vfs/syscall.rs +++ b/kernel/src/filesystem/vfs/syscall.rs @@ -978,6 +978,8 @@ impl Syscall { .ok_or(SystemError::EBADF)?; let new_file = old_file.try_clone().ok_or(SystemError::EBADF)?; + // dup默认非cloexec + new_file.set_close_on_exec(false); // 申请文件描述符,并把文件对象存入其中 let res = fd_table_guard.alloc_fd(new_file, None).map(|x| x as usize); return res; @@ -1029,6 +1031,8 @@ impl Syscall { .get_file_by_fd(oldfd) .ok_or(SystemError::EBADF)?; let new_file = old_file.try_clone().ok_or(SystemError::EBADF)?; + // dup2默认非cloexec + new_file.set_close_on_exec(false); // 申请文件描述符,并把文件对象存入其中 let res = fd_table_guard .alloc_fd(new_file, Some(newfd))