mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 14:16:47 +00:00
完善pty,目前pty能够支持ssh (#708)
This commit is contained in:
parent
4b0170bd6b
commit
9365e8017b
@ -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<TtyCore>, 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<TtyCore>, _old_termios: Termios) -> Result<(), SystemError> {
|
||||
fn set_termios(&self, tty: Arc<TtyCore>, 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<TtyCore>) -> 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<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(
|
||||
|
@ -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,
|
||||
|
@ -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<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 {
|
||||
pub fn new(driver: Arc<TtyDriver>, index: usize) -> Arc<Self> {
|
||||
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<WindowSize> {
|
||||
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<TtyCore>) -> Result<(), SystemError> {
|
||||
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! {
|
||||
|
@ -134,10 +134,10 @@ impl IndexNode for TtyDevice {
|
||||
mut data: SpinLockGuard<FilePrivateData>,
|
||||
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::<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) {
|
||||
Ok(_) => {
|
||||
return Ok(0);
|
||||
|
@ -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<TtyCore>) -> Result<(), SystemError>;
|
||||
|
||||
fn resize(&self, _tty: Arc<TtyCore>, _winsize: WindowSize) -> Result<(), SystemError>;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
@ -122,7 +122,7 @@ pub struct NTtyData {
|
||||
read_flags: StaticBitmap<NTTY_BUFSIZE>,
|
||||
char_map: StaticBitmap<256>,
|
||||
|
||||
tty: Option<Weak<TtyCore>>,
|
||||
tty: Weak<TtyCore>,
|
||||
}
|
||||
|
||||
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<usize, SystemError> {
|
||||
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<TtyCore>) -> 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);
|
||||
}
|
||||
|
@ -242,6 +242,14 @@ impl TtyOperation for TtyConsoleDriverInner {
|
||||
fn close(&self, _tty: Arc<TtyCore>) -> Result<(), SystemError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn resize(
|
||||
&self,
|
||||
_tty: Arc<TtyCore>,
|
||||
_winsize: super::termios::WindowSize,
|
||||
) -> Result<(), SystemError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -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)?;
|
||||
|
||||
// 把文件描述符数组对应位置设置为空
|
||||
|
@ -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))
|
||||
|
Loading…
x
Reference in New Issue
Block a user