Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 69 additions & 5 deletions kernel/src/driver/tty/pty/unix98pty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -171,15 +217,33 @@ 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());
}

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(
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/driver/tty/termios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
27 changes: 26 additions & 1 deletion kernel/src/driver/tty/tty_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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)]
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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! {
Expand Down
23 changes: 20 additions & 3 deletions kernel/src/driver/tty/tty_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 4 additions & 2 deletions kernel/src/driver/tty/tty_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::{
};

use super::{
termios::Termios,
termios::{Termios, WindowSize},
tty_core::{TtyCore, TtyCoreData},
tty_ldisc::TtyLdiscManager,
tty_port::{DefaultTtyPort, TtyPort},
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)]
Expand Down
8 changes: 4 additions & 4 deletions kernel/src/driver/tty/tty_ldisc/ntty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
}
}
Expand Down Expand Up @@ -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());

// 如果读取数量大于了可用空间,则取最小的为真正的写入数量
Expand Down Expand Up @@ -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);
}
Expand Down
8 changes: 8 additions & 0 deletions kernel/src/driver/tty/virtual_terminal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
5 changes: 0 additions & 5 deletions kernel/src/filesystem/vfs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;

// 把文件描述符数组对应位置设置为空
Expand Down
4 changes: 4 additions & 0 deletions kernel/src/filesystem/vfs/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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))
Expand Down
Loading