Skip to content

Commit 9365e80

Browse files
authored
完善pty,目前pty能够支持ssh (#708)
1 parent 4b0170b commit 9365e80

File tree

9 files changed

+136
-21
lines changed

9 files changed

+136
-21
lines changed

kernel/src/driver/tty/pty/unix98pty.rs

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use system_error::SystemError;
33

44
use crate::{
55
driver::tty::{
6-
termios::Termios,
6+
termios::{ControlCharIndex, ControlMode, InputMode, LocalMode, Termios},
77
tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyIoctlCmd, TtyPacketStatus},
88
tty_device::TtyFilePrivateData,
99
tty_driver::{TtyDriver, TtyDriverPrivateData, TtyDriverSubType, TtyOperation},
@@ -76,7 +76,7 @@ impl TtyOperation for Unix98PtyDriverInner {
7676
fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError> {
7777
let core = tty.core();
7878
if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtyMaster {
79-
return Err(SystemError::ENOSYS);
79+
return Err(SystemError::ENOIOCTLCMD);
8080
}
8181

8282
match cmd {
@@ -104,12 +104,58 @@ impl TtyOperation for Unix98PtyDriverInner {
104104
}
105105
}
106106

107-
fn set_termios(&self, tty: Arc<TtyCore>, _old_termios: Termios) -> Result<(), SystemError> {
107+
fn set_termios(&self, tty: Arc<TtyCore>, old_termios: Termios) -> Result<(), SystemError> {
108108
let core = tty.core();
109109
if core.driver().tty_driver_sub_type() != TtyDriverSubType::PtySlave {
110110
return Err(SystemError::ENOSYS);
111111
}
112-
todo!()
112+
113+
let core = tty.core();
114+
if let Some(link) = core.link() {
115+
let link = link.core();
116+
if link.contorl_info_irqsave().packet {
117+
let curr_termios = *core.termios();
118+
let extproc = old_termios.local_mode.contains(LocalMode::EXTPROC)
119+
| curr_termios.local_mode.contains(LocalMode::EXTPROC);
120+
121+
let old_flow = old_termios.input_mode.contains(InputMode::IXON)
122+
&& old_termios.control_characters[ControlCharIndex::VSTOP] == 0o023
123+
&& old_termios.control_characters[ControlCharIndex::VSTART] == 0o021;
124+
125+
let new_flow = curr_termios.input_mode.contains(InputMode::IXON)
126+
&& curr_termios.control_characters[ControlCharIndex::VSTOP] == 0o023
127+
&& curr_termios.control_characters[ControlCharIndex::VSTART] == 0o021;
128+
129+
if old_flow != new_flow || extproc {
130+
let mut ctrl = core.contorl_info_irqsave();
131+
if old_flow != new_flow {
132+
ctrl.pktstatus.remove(
133+
TtyPacketStatus::TIOCPKT_DOSTOP | TtyPacketStatus::TIOCPKT_NOSTOP,
134+
);
135+
136+
if new_flow {
137+
ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_DOSTOP);
138+
} else {
139+
ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_NOSTOP);
140+
}
141+
}
142+
143+
if extproc {
144+
ctrl.pktstatus.insert(TtyPacketStatus::TIOCPKT_IOCTL);
145+
}
146+
147+
link.read_wq().wakeup_all();
148+
}
149+
}
150+
}
151+
let mut termois = core.termios_write();
152+
termois
153+
.control_mode
154+
.remove(ControlMode::CSIZE | ControlMode::PARENB);
155+
termois
156+
.control_mode
157+
.insert(ControlMode::CS8 | ControlMode::CREAD);
158+
Ok(())
113159
}
114160

115161
fn start(&self, core: &TtyCoreData) -> Result<(), SystemError> {
@@ -171,15 +217,33 @@ impl TtyOperation for Unix98PtyDriverInner {
171217
fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
172218
let driver = tty.core().driver();
173219

174-
driver.ttys().remove(&tty.core().index());
175220
if tty.core().driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave {
221+
driver.ttys().remove(&tty.core().index());
176222
let pts_root_inode =
177223
ROOT_INODE().lookup_follow_symlink("/dev/pts", VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
178224
let _ = pts_root_inode.unlink(&tty.core().index().to_string());
179225
}
180226

181227
Ok(())
182228
}
229+
230+
fn resize(
231+
&self,
232+
tty: Arc<TtyCore>,
233+
winsize: crate::driver::tty::termios::WindowSize,
234+
) -> Result<(), SystemError> {
235+
let core = tty.core();
236+
if *core.window_size() == winsize {
237+
return Ok(());
238+
}
239+
240+
// TODO:向进程发送SIGWINCH信号
241+
242+
*core.window_size_write() = winsize;
243+
*core.link().unwrap().core().window_size_write() = winsize;
244+
245+
Ok(())
246+
}
183247
}
184248

185249
pub fn ptmx_open(

kernel/src/driver/tty/termios.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::tty_ldisc::LineDisciplineType;
22

33
/// ## 窗口大小
44
#[repr(C)]
5-
#[derive(Debug, Default, Clone, Copy)]
5+
#[derive(Debug, Default, Clone, Copy, PartialEq)]
66
pub struct WindowSize {
77
/// 行
88
pub row: u16,

kernel/src/driver/tty/tty_core.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use alloc::{
1212
use system_error::SystemError;
1313

1414
use crate::{
15-
driver::serial::serial8250::send_to_default_serial8250_port,
15+
driver::{serial::serial8250::send_to_default_serial8250_port, tty::pty::ptm_driver},
1616
libs::{
1717
rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard},
1818
spinlock::{SpinLock, SpinLockGuard},
@@ -42,6 +42,14 @@ pub struct TtyCore {
4242
line_discipline: Arc<dyn TtyLineDiscipline>,
4343
}
4444

45+
impl Drop for TtyCore {
46+
fn drop(&mut self) {
47+
if self.core.driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave {
48+
ptm_driver().ttys().remove(&self.core().index);
49+
}
50+
}
51+
}
52+
4553
impl TtyCore {
4654
pub fn new(driver: Arc<TtyDriver>, index: usize) -> Arc<Self> {
4755
let name = driver.tty_line_name(index);
@@ -232,7 +240,9 @@ impl TtyCore {
232240
let tmp = termios.control_mode;
233241
termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB;
234242

243+
drop(termios);
235244
let ret = tty.set_termios(tty.clone(), old_termios);
245+
let mut termios = tty.core().termios_write();
236246
if ret.is_err() {
237247
termios.control_mode &= ControlMode::HUPCL | ControlMode::CREAD | ControlMode::CLOCAL;
238248
termios.control_mode |= old_termios.control_mode
@@ -247,6 +257,12 @@ impl TtyCore {
247257

248258
Ok(())
249259
}
260+
261+
pub fn tty_do_resize(&self, windowsize: WindowSize) -> Result<(), SystemError> {
262+
// TODO: 向前台进程发送信号
263+
*self.core.window_size_write() = windowsize;
264+
Ok(())
265+
}
250266
}
251267

252268
#[derive(Debug, Default)]
@@ -394,6 +410,11 @@ impl TtyCoreData {
394410
self.window_size.read()
395411
}
396412

413+
#[inline]
414+
pub fn window_size_write(&self) -> RwLockWriteGuard<WindowSize> {
415+
self.window_size.write()
416+
}
417+
397418
#[inline]
398419
pub fn is_closing(&self) -> bool {
399420
self.closing.load(core::sync::atomic::Ordering::SeqCst)
@@ -511,6 +532,10 @@ impl TtyOperation for TtyCore {
511532
fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError> {
512533
self.core().tty_driver.driver_funcs().close(tty)
513534
}
535+
536+
fn resize(&self, tty: Arc<TtyCore>, winsize: WindowSize) -> Result<(), SystemError> {
537+
self.core.tty_driver.driver_funcs().resize(tty, winsize)
538+
}
514539
}
515540

516541
bitflags! {

kernel/src/driver/tty/tty_device.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,10 @@ impl IndexNode for TtyDevice {
134134
mut data: SpinLockGuard<FilePrivateData>,
135135
mode: &crate::filesystem::vfs::file::FileMode,
136136
) -> Result<(), SystemError> {
137+
if let FilePrivateData::Tty(_) = &*data {
138+
return Ok(());
139+
}
137140
if self.tty_type == TtyType::Pty(PtyType::Ptm) {
138-
if let FilePrivateData::Tty(_) = &*data {
139-
return Ok(());
140-
}
141141
return ptmx_open(data, mode);
142142
}
143143
let dev_num = self.metadata()?.raw_dev;
@@ -360,6 +360,23 @@ impl IndexNode for TtyDevice {
360360
}
361361
return Ok(0);
362362
}
363+
TtyIoctlCmd::TIOCSWINSZ => {
364+
let reader = UserBufferReader::new(
365+
arg as *const (),
366+
core::mem::size_of::<WindowSize>(),
367+
true,
368+
)?;
369+
370+
let user_winsize = reader.read_one_from_user::<WindowSize>(0)?;
371+
372+
let ret = tty.resize(tty.clone(), *user_winsize);
373+
374+
if ret != Err(SystemError::ENOSYS) {
375+
return ret.map(|_| 0);
376+
} else {
377+
return tty.tty_do_resize(*user_winsize).map(|_| 0);
378+
}
379+
}
363380
_ => match TtyJobCtrlManager::job_ctrl_ioctl(tty.clone(), cmd, arg) {
364381
Ok(_) => {
365382
return Ok(0);

kernel/src/driver/tty/tty_driver.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::{
2727
};
2828

2929
use super::{
30-
termios::Termios,
30+
termios::{Termios, WindowSize},
3131
tty_core::{TtyCore, TtyCoreData},
3232
tty_ldisc::TtyLdiscManager,
3333
tty_port::{DefaultTtyPort, TtyPort},
@@ -273,7 +273,7 @@ impl TtyDriver {
273273
tty.set_port(ports[core.index()].clone());
274274
}
275275

276-
TtyLdiscManager::ldisc_setup(tty.clone(), None)?;
276+
TtyLdiscManager::ldisc_setup(tty.clone(), tty.core().link())?;
277277

278278
Ok(tty)
279279
}
@@ -445,6 +445,8 @@ pub trait TtyOperation: Sync + Send + Debug {
445445
}
446446

447447
fn close(&self, tty: Arc<TtyCore>) -> Result<(), SystemError>;
448+
449+
fn resize(&self, _tty: Arc<TtyCore>, _winsize: WindowSize) -> Result<(), SystemError>;
448450
}
449451

450452
#[allow(dead_code)]

kernel/src/driver/tty/tty_ldisc/ntty.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ pub struct NTtyData {
122122
read_flags: StaticBitmap<NTTY_BUFSIZE>,
123123
char_map: StaticBitmap<256>,
124124

125-
tty: Option<Weak<TtyCore>>,
125+
tty: Weak<TtyCore>,
126126
}
127127

128128
impl NTtyData {
@@ -151,7 +151,7 @@ impl NTtyData {
151151
echo_buf: [0; NTTY_BUFSIZE],
152152
read_flags: StaticBitmap::new(),
153153
char_map: StaticBitmap::new(),
154-
tty: None,
154+
tty: Weak::default(),
155155
no_room: false,
156156
}
157157
}
@@ -1168,7 +1168,7 @@ impl NTtyData {
11681168
nr: usize,
11691169
) -> Result<usize, SystemError> {
11701170
let mut nr = nr;
1171-
let tty = self.tty.clone().unwrap().upgrade().unwrap();
1171+
let tty = self.tty.upgrade().unwrap();
11721172
let space = tty.write_room(tty.core());
11731173

11741174
// 如果读取数量大于了可用空间,则取最小的为真正的写入数量
@@ -1541,7 +1541,7 @@ impl NTtyData {
15411541
impl TtyLineDiscipline for NTtyLinediscipline {
15421542
fn open(&self, tty: Arc<TtyCore>) -> Result<(), system_error::SystemError> {
15431543
// 反向绑定tty到disc
1544-
self.disc_data().tty = Some(Arc::downgrade(&tty));
1544+
self.disc_data().tty = Arc::downgrade(&tty);
15451545
// 特定的tty设备在这里可能需要取消端口节流
15461546
return self.set_termios(tty, None);
15471547
}

kernel/src/driver/tty/virtual_terminal/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,14 @@ impl TtyOperation for TtyConsoleDriverInner {
242242
fn close(&self, _tty: Arc<TtyCore>) -> Result<(), SystemError> {
243243
Ok(())
244244
}
245+
246+
fn resize(
247+
&self,
248+
_tty: Arc<TtyCore>,
249+
_winsize: super::termios::WindowSize,
250+
) -> Result<(), SystemError> {
251+
todo!()
252+
}
245253
}
246254

247255
#[derive(Debug, Clone)]

kernel/src/filesystem/vfs/file.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -634,11 +634,6 @@ impl FileDescriptorVec {
634634
///
635635
/// - `fd` 文件描述符序号
636636
pub fn drop_fd(&mut self, fd: i32) -> Result<(), SystemError> {
637-
// 判断文件描述符的数字是否超过限制
638-
if !FileDescriptorVec::validate_fd(fd) {
639-
return Err(SystemError::EBADF);
640-
}
641-
642637
self.get_file_by_fd(fd).ok_or(SystemError::EBADF)?;
643638

644639
// 把文件描述符数组对应位置设置为空

kernel/src/filesystem/vfs/syscall.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,8 @@ impl Syscall {
978978
.ok_or(SystemError::EBADF)?;
979979

980980
let new_file = old_file.try_clone().ok_or(SystemError::EBADF)?;
981+
// dup默认非cloexec
982+
new_file.set_close_on_exec(false);
981983
// 申请文件描述符,并把文件对象存入其中
982984
let res = fd_table_guard.alloc_fd(new_file, None).map(|x| x as usize);
983985
return res;
@@ -1029,6 +1031,8 @@ impl Syscall {
10291031
.get_file_by_fd(oldfd)
10301032
.ok_or(SystemError::EBADF)?;
10311033
let new_file = old_file.try_clone().ok_or(SystemError::EBADF)?;
1034+
// dup2默认非cloexec
1035+
new_file.set_close_on_exec(false);
10321036
// 申请文件描述符,并把文件对象存入其中
10331037
let res = fd_table_guard
10341038
.alloc_fd(new_file, Some(newfd))

0 commit comments

Comments
 (0)