完善pty,目前pty能够支持ssh (#708)

This commit is contained in:
GnoCiYeH 2024-04-10 19:00:12 +08:00 committed by GitHub
parent 4b0170bd6b
commit 9365e8017b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 136 additions and 21 deletions

View File

@ -3,7 +3,7 @@ use system_error::SystemError;
use crate::{ use crate::{
driver::tty::{ driver::tty::{
termios::Termios, termios::{ControlCharIndex, ControlMode, InputMode, LocalMode, Termios},
tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd, TtyPacketStatus}, tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd, TtyPacketStatus},
tty_device::TtyFilePrivateData, tty_device::TtyFilePrivateData,
tty_driver::{TtyDriver, TtyDriverPrivateData, TtyDriverSubType, TtyOperation}, tty_driver::{TtyDriver, TtyDriverPrivateData, TtyDriverSubType, TtyOperation},
@ -76,7 +76,7 @@ impl TtyOperation for Unix98PtyDriverInner {
fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError> { fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError> {
let core = tty.core(); let core = tty.core();
if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtyMaster { if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtyMaster {
return Err(SystemError::ENOSYS); return Err(SystemError::ENOIOCTLCMD);
} }
match cmd { match cmd {
@ -104,12 +104,58 @@ impl TtyOperation for Unix98PtyDriverInner {
} }
} }
fn set_termios(&self, tty: Arc<TtyCore>, _old_termios: Termios) -> Result<(), SystemError> { fn set_termios(&self, tty: Arc<TtyCore>, old_termios: Termios) -> Result<(), SystemError> {
let core = tty.core(); let core = tty.core();
if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave { if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
return Err(SystemError::ENOSYS); 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> { fn start(&self, core: &TtyCoreData) -> Result<(), SystemError> {
@ -171,8 +217,8 @@ impl TtyOperation for Unix98PtyDriverInner {
fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> { fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
let driver = tty.core().driver(); let driver = tty.core().driver();
driver.ttys().remove(&tty.core().index());
if tty.core().driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave { if tty.core().driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave {
driver.ttys().remove(&tty.core().index());
let pts_root_inode = let pts_root_inode =
ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?; ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
let _ = pts_root_inode.unlink(&tty.core().index().to_string()); let _ = pts_root_inode.unlink(&tty.core().index().to_string());
@ -180,6 +226,24 @@ impl TtyOperation for Unix98PtyDriverInner {
Ok(()) Ok(())
} }
fn resize(
&self,
tty: Arc<TtyCore>,
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( pub fn ptmx_open(

View File

@ -2,7 +2,7 @@ use super::tty_ldisc::LineDisciplineType;
/// ## 窗口大小 /// ## 窗口大小
#[repr(C)] #[repr(C)]
#[derive(Debug, Default, Clone, Copy)] #[derive(Debug, Default, Clone, Copy, PartialEq)]
pub struct WindowSize { pub struct WindowSize {
/// 行 /// 行
pub row: u16, pub row: u16,

View File

@ -12,7 +12,7 @@ use alloc::{
use system_error::SystemError; use system_error::SystemError;
use crate::{ use crate::{
driver::serial::serial8250::send_to_default_serial8250_port, driver::{serial::serial8250::send_to_default_serial8250_port, tty::pty::ptm_driver},
libs::{ libs::{
rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard}, rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard},
spinlock::{SpinLock, SpinLockGuard}, spinlock::{SpinLock, SpinLockGuard},
@ -42,6 +42,14 @@ pub struct TtyCore {
line_discipline: Arc<dyn TtyLineDiscipline>, line_discipline: Arc<dyn TtyLineDiscipline>,
} }
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 { impl TtyCore {
pub fn new(driver: Arc<TtyDriver>, index: usize) -> Arc<Self> { pub fn new(driver: Arc<TtyDriver>, index: usize) -> Arc<Self> {
let name = driver.tty_line_name(index); let name = driver.tty_line_name(index);
@ -232,7 +240,9 @@ impl TtyCore {
let tmp = termios.control_mode; let tmp = termios.control_mode;
termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB; termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB;
drop(termios);
let ret = tty.set_termios(tty.clone(), old_termios); let ret = tty.set_termios(tty.clone(), old_termios);
let mut termios = tty.core().termios_write();
if ret.is_err() { if ret.is_err() {
termios.control_mode &= ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL; termios.control_mode &= ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL;
termios.control_mode |= old_termios.control_mode termios.control_mode |= old_termios.control_mode
@ -247,6 +257,12 @@ impl TtyCore {
Ok(()) Ok(())
} }
pub fn tty_do_resize(&self, windowsize: WindowSize) -> Result<(), SystemError> {
// TODO: 向前台进程发送信号
*self.core.window_size_write() = windowsize;
Ok(())
}
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -394,6 +410,11 @@ impl TtyCoreData {
self.window_size.read() self.window_size.read()
} }
#[inline]
pub fn window_size_write(&self) -> RwLockWriteGuard<WindowSize> {
self.window_size.write()
}
#[inline] #[inline]
pub fn is_closing(&self) -> bool { pub fn is_closing(&self) -> bool {
self.closing.load(core::sync::atomic::Ordering::SeqCst) self.closing.load(core::sync::atomic::Ordering::SeqCst)
@ -511,6 +532,10 @@ impl TtyOperation for TtyCore {
fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> { fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
self.core().tty_driver.driver_funcs().close(tty) self.core().tty_driver.driver_funcs().close(tty)
} }
fn resize(&self, tty: Arc<TtyCore>, winsize: WindowSize) -> Result<(), SystemError> {
self.core.tty_driver.driver_funcs().resize(tty, winsize)
}
} }
bitflags! { bitflags! {

View File

@ -134,10 +134,10 @@ impl IndexNode for TtyDevice {
mut data: SpinLockGuard<FilePrivateData>, mut data: SpinLockGuard<FilePrivateData>,
mode: &crate::filesystem::vfs::file::FileMode, mode: &crate::filesystem::vfs::file::FileMode,
) -> Result<(), SystemError> { ) -> Result<(), SystemError> {
if let FilePrivateData::Tty(_) = &*data {
return Ok(());
}
if self.tty_type == TtyType::Pty(PtyType::Ptm) { if self.tty_type == TtyType::Pty(PtyType::Ptm) {
if let FilePrivateData::Tty(_) = &*data {
return Ok(());
}
return ptmx_open(data, mode); return ptmx_open(data, mode);
} }
let dev_num = self.metadata()?.raw_dev; let dev_num = self.metadata()?.raw_dev;
@ -360,6 +360,23 @@ impl IndexNode for TtyDevice {
} }
return Ok(0); return Ok(0);
} }
TtyIoctlCmd::TIOCSWINSZ => {
let reader = UserBufferReader::new(
arg as *const (),
core::mem::size_of::<WindowSize>(),
true,
)?;
let user_winsize = reader.read_one_from_user::<WindowSize>(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) { _ => match TtyJobCtrlManager::job_ctrl_ioctl(tty.clone(), cmd, arg) {
Ok(_) => { Ok(_) => {
return Ok(0); return Ok(0);

View File

@ -27,7 +27,7 @@ use crate::{
}; };
use super::{ use super::{
termios::Termios, termios::{Termios, WindowSize},
tty_core::{TtyCore, TtyCoreData}, tty_core::{TtyCore, TtyCoreData},
tty_ldisc::TtyLdiscManager, tty_ldisc::TtyLdiscManager,
tty_port::{DefaultTtyPort, TtyPort}, tty_port::{DefaultTtyPort, TtyPort},
@ -273,7 +273,7 @@ impl TtyDriver {
tty.set_port(ports[core.index()].clone()); tty.set_port(ports[core.index()].clone());
} }
TtyLdiscManager::ldisc_setup(tty.clone(), None)?; TtyLdiscManager::ldisc_setup(tty.clone(), tty.core().link())?;
Ok(tty) Ok(tty)
} }
@ -445,6 +445,8 @@ pub trait TtyOperation: Sync + Send + Debug {
} }
fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>; fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
fn resize(&self, _tty: Arc<TtyCore>, _winsize: WindowSize) -> Result<(), SystemError>;
} }
#[allow(dead_code)] #[allow(dead_code)]

View File

@ -122,7 +122,7 @@ pub struct NTtyData {
read_flags: StaticBitmap<NTTY_BUFSIZE>, read_flags: StaticBitmap<NTTY_BUFSIZE>,
char_map: StaticBitmap<256>, char_map: StaticBitmap<256>,
tty: Option<Weak<TtyCore>>, tty: Weak<TtyCore>,
} }
impl NTtyData { impl NTtyData {
@ -151,7 +151,7 @@ impl NTtyData {
echo_buf: [0; NTTY_BUFSIZE], echo_buf: [0; NTTY_BUFSIZE],
read_flags: StaticBitmap::new(), read_flags: StaticBitmap::new(),
char_map: StaticBitmap::new(), char_map: StaticBitmap::new(),
tty: None, tty: Weak::default(),
no_room: false, no_room: false,
} }
} }
@ -1168,7 +1168,7 @@ impl NTtyData {
nr: usize, nr: usize,
) -> Result<usize, SystemError> { ) -> Result<usize, SystemError> {
let mut nr = nr; 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()); let space = tty.write_room(tty.core());
// 如果读取数量大于了可用空间,则取最小的为真正的写入数量 // 如果读取数量大于了可用空间,则取最小的为真正的写入数量
@ -1541,7 +1541,7 @@ impl NTtyData {
impl TtyLineDiscipline for NTtyLinediscipline { impl TtyLineDiscipline for NTtyLinediscipline {
fn open(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> { fn open(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
// 反向绑定tty到disc // 反向绑定tty到disc
self.disc_data().tty = Some(Arc::downgrade(&tty)); self.disc_data().tty = Arc::downgrade(&tty);
// 特定的tty设备在这里可能需要取消端口节流 // 特定的tty设备在这里可能需要取消端口节流
return self.set_termios(tty, None); return self.set_termios(tty, None);
} }

View File

@ -242,6 +242,14 @@ impl TtyOperation for TtyConsoleDriverInner {
fn close(&self, _tty: Arc<TtyCore>) -> Result<(), SystemError> { fn close(&self, _tty: Arc<TtyCore>) -> Result<(), SystemError> {
Ok(()) Ok(())
} }
fn resize(
&self,
_tty: Arc<TtyCore>,
_winsize: super::termios::WindowSize,
) -> Result<(), SystemError> {
todo!()
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View File

@ -634,11 +634,6 @@ impl FileDescriptorVec {
/// ///
/// - `fd` 文件描述符序号 /// - `fd` 文件描述符序号
pub fn drop_fd(&mut self, fd: i32) -> Result<(), SystemError> { 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)?; self.get_file_by_fd(fd).ok_or(SystemError::EBADF)?;
// 把文件描述符数组对应位置设置为空 // 把文件描述符数组对应位置设置为空

View File

@ -978,6 +978,8 @@ impl Syscall {
.ok_or(SystemError::EBADF)?; .ok_or(SystemError::EBADF)?;
let new_file = old_file.try_clone().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); let res = fd_table_guard.alloc_fd(new_file, None).map(|x| x as usize);
return res; return res;
@ -1029,6 +1031,8 @@ impl Syscall {
.get_file_by_fd(oldfd) .get_file_by_fd(oldfd)
.ok_or(SystemError::EBADF)?; .ok_or(SystemError::EBADF)?;
let new_file = old_file.try_clone().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 let res = fd_table_guard
.alloc_fd(new_file, Some(newfd)) .alloc_fd(new_file, Some(newfd))