mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 10:15:03 +00:00
* 添加busybox的编译 * 完善tty job control的逻辑 * 修改copy_sighand的逻辑,符合Linux语义 * 以busybox作为启动shell去运行 * 修改setsid的逻辑 * 解决前台进程组无法处理信号的问题 * 移除ProcessBasicInfo其中的pgid和sid信息 * 修改setsid * 新增get_pcb_info * 在etc目录下新增必要的文件 * 改用busybox init作为引导程序 * 恢复dragonreach文件 * 修改busybox编译选项,能够读取环境变量 * 先让SYS_RT_SIGTIMEDWAIT返回Ok(0),能够正常进入系统 * 一些小更改 * 删除get_pcb_info * 增加对默认termios的判断 * 完成backspace的修复 * 更改inittab,在shell启动之后更改termios * 增加executable_path信息 * 补充proc下的exe链接文件以及读取逻辑 * 更改PosixTermios,使用stty完成erase的设置 * 用busybox作为引导程序 * 修改波特率的获取 * 修改函数方法 * 在baud_rate方法中添加对于cbaud的与操作 * 为rv64下的SigSet实现From<Signal> * refactor(driver): 移除`#[derive(Debug)]`并手动实现`Debug` trait 移除`VirtIOBlkDevice`、`VirtIOConsoleDevice`和`VirtIONetDevice`的`#[derive(Debug)]`,并手动实现`Debug` trait以提供更详细的调试信息。 Co-authored-by: longjin <longjin@DragonOS.org>
217 lines
6.8 KiB
Rust
217 lines
6.8 KiB
Rust
use alloc::sync::Arc;
|
||
use system_error::SystemError;
|
||
|
||
use crate::{
|
||
arch::ipc::signal::{SigSet, Signal},
|
||
mm::VirtAddr,
|
||
process::{process_group::Pgid, Pid, ProcessFlags, ProcessManager},
|
||
syscall::{
|
||
user_access::{UserBufferReader, UserBufferWriter},
|
||
Syscall,
|
||
},
|
||
};
|
||
|
||
use super::tty_core::{TtyCore, TtyIoctlCmd};
|
||
|
||
pub struct TtyJobCtrlManager;
|
||
|
||
impl TtyJobCtrlManager {
|
||
/// ### 设置当前进程的tty
|
||
pub fn proc_set_tty(tty: Arc<TtyCore>) {
|
||
let core = tty.core();
|
||
let pcb = ProcessManager::current_pcb();
|
||
|
||
let mut ctrl = core.contorl_info_irqsave();
|
||
ctrl.set_info_by_pcb(pcb.clone());
|
||
drop(ctrl);
|
||
|
||
let mut singal = pcb.sig_info_mut();
|
||
singal.set_tty(Some(tty.clone()));
|
||
}
|
||
|
||
/// ### 检查tty
|
||
pub fn tty_check_change(tty: Arc<TtyCore>, sig: Signal) -> Result<(), SystemError> {
|
||
let pcb = ProcessManager::current_pcb();
|
||
|
||
if pcb.sig_info_irqsave().tty().is_none()
|
||
|| !Arc::ptr_eq(&pcb.sig_info_irqsave().tty().unwrap(), &tty)
|
||
{
|
||
return Ok(());
|
||
}
|
||
|
||
let pgid = pcb.pgid();
|
||
|
||
let ctrl = tty.core().contorl_info_irqsave();
|
||
let tty_pgid = ctrl.pgid;
|
||
drop(ctrl);
|
||
|
||
if tty_pgid.is_some() && tty_pgid.unwrap() != pgid {
|
||
if pcb
|
||
.sig_info_irqsave()
|
||
.sig_blocked()
|
||
.contains(SigSet::from(sig))
|
||
|| pcb.sig_struct_irqsave().handlers[sig as usize - 1].is_ignore()
|
||
{
|
||
// 忽略该信号
|
||
if sig == Signal::SIGTTIN {
|
||
return Err(SystemError::EIO);
|
||
}
|
||
} else if ProcessManager::is_current_pgrp_orphaned() {
|
||
return Err(SystemError::EIO);
|
||
} else {
|
||
Syscall::kill_process_group(pgid, sig)?;
|
||
ProcessManager::current_pcb()
|
||
.flags()
|
||
.insert(ProcessFlags::HAS_PENDING_SIGNAL);
|
||
log::debug!("job_ctrl_ioctl: kill. pgid: {pgid}, tty_pgid: {tty_pgid:?}");
|
||
return Err(SystemError::ERESTARTSYS);
|
||
}
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
pub fn job_ctrl_ioctl(
|
||
real_tty: Arc<TtyCore>,
|
||
cmd: u32,
|
||
arg: usize,
|
||
) -> Result<usize, SystemError> {
|
||
match cmd {
|
||
TtyIoctlCmd::TIOCSPGRP => Self::tiocspgrp(real_tty, arg),
|
||
TtyIoctlCmd::TIOCGPGRP => Self::tiocgpgrp(real_tty, arg),
|
||
TtyIoctlCmd::TIOCGSID => Self::tiocgsid(real_tty, arg),
|
||
TtyIoctlCmd::TIOCSCTTY => Self::tiocsctty(real_tty),
|
||
_ => {
|
||
return Err(SystemError::ENOIOCTLCMD);
|
||
}
|
||
}
|
||
}
|
||
|
||
fn tiocsctty(real_tty: Arc<TtyCore>) -> Result<usize, SystemError> {
|
||
let current = ProcessManager::current_pcb();
|
||
// log::debug!("job_ctrl_ioctl: TIOCSCTTY,current: {:?}", current.pid());
|
||
if current.is_session_leader()
|
||
&& real_tty.core().contorl_info_irqsave().session.unwrap() == current.sid()
|
||
{
|
||
return Ok(0);
|
||
}
|
||
|
||
if !current.is_session_leader() || current.sig_info_irqsave().tty().is_some() {
|
||
return Err(SystemError::EPERM);
|
||
}
|
||
|
||
//todo 权限检查?
|
||
// https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/tty/tty_jobctrl.c#tiocsctty
|
||
if let Some(sid) = real_tty.core().contorl_info_irqsave().session {
|
||
//todo 目前只有一个tty设备,所以选择复用1号进程的tty,因此修改1号进程的tty暂时被允许
|
||
if sid != Pid::new(1) {
|
||
return Err(SystemError::EPERM);
|
||
}
|
||
}
|
||
|
||
Self::proc_set_tty(real_tty);
|
||
Ok(0)
|
||
}
|
||
|
||
fn tiocgpgrp(real_tty: Arc<TtyCore>, arg: usize) -> Result<usize, SystemError> {
|
||
// log::debug!("job_ctrl_ioctl: TIOCGPGRP");
|
||
let current = ProcessManager::current_pcb();
|
||
if current.sig_info_irqsave().tty().is_some()
|
||
&& !Arc::ptr_eq(¤t.sig_info_irqsave().tty().unwrap(), &real_tty)
|
||
{
|
||
return Err(SystemError::ENOTTY);
|
||
}
|
||
|
||
let mut user_writer = UserBufferWriter::new(
|
||
VirtAddr::new(arg).as_ptr::<i32>(),
|
||
core::mem::size_of::<i32>(),
|
||
true,
|
||
)?;
|
||
|
||
user_writer.copy_one_to_user(
|
||
&(real_tty
|
||
.core()
|
||
.contorl_info_irqsave()
|
||
.pgid
|
||
.unwrap_or(Pid::new(1))
|
||
.data() as i32),
|
||
0,
|
||
)?;
|
||
|
||
return Ok(0);
|
||
}
|
||
|
||
fn tiocgsid(real_tty: Arc<TtyCore>, arg: usize) -> Result<usize, SystemError> {
|
||
// log::debug!("job_ctrl_ioctl: TIOCGSID");
|
||
let current = ProcessManager::current_pcb();
|
||
if current.sig_info_irqsave().tty().is_some()
|
||
&& !Arc::ptr_eq(¤t.sig_info_irqsave().tty().unwrap(), &real_tty)
|
||
{
|
||
return Err(SystemError::ENOTTY);
|
||
}
|
||
|
||
let guard = real_tty.core().contorl_info_irqsave();
|
||
if guard.session.is_none() {
|
||
return Err(SystemError::ENOTTY);
|
||
}
|
||
let sid = guard.session.unwrap();
|
||
drop(guard);
|
||
|
||
let mut user_writer = UserBufferWriter::new(
|
||
VirtAddr::new(arg).as_ptr::<i32>(),
|
||
core::mem::size_of::<i32>(),
|
||
true,
|
||
)?;
|
||
user_writer.copy_one_to_user(&(sid.data() as i32), 0)?;
|
||
|
||
return Ok(0);
|
||
}
|
||
|
||
fn tiocspgrp(real_tty: Arc<TtyCore>, arg: usize) -> Result<usize, SystemError> {
|
||
// log::debug!("job_ctrl_ioctl: TIOCSPGRP");
|
||
match Self::tty_check_change(real_tty.clone(), Signal::SIGTTOU) {
|
||
Ok(_) => {}
|
||
Err(e) => {
|
||
if e == SystemError::EIO {
|
||
return Err(SystemError::ENOTTY);
|
||
}
|
||
return Err(e);
|
||
}
|
||
};
|
||
|
||
let user_reader = UserBufferReader::new(
|
||
VirtAddr::new(arg).as_ptr::<i32>(),
|
||
core::mem::size_of::<i32>(),
|
||
true,
|
||
)?;
|
||
|
||
let pgrp = user_reader.read_one_from_user::<i32>(0)?;
|
||
|
||
let current = ProcessManager::current_pcb();
|
||
|
||
let mut ctrl = real_tty.core().contorl_info_irqsave();
|
||
|
||
if current.sig_info_irqsave().tty().is_none()
|
||
|| !Arc::ptr_eq(
|
||
¤t.sig_info_irqsave().tty().clone().unwrap(),
|
||
&real_tty,
|
||
)
|
||
|| ctrl.session.is_none()
|
||
|| ctrl.session.unwrap() != current.sid()
|
||
{
|
||
return Err(SystemError::ENOTTY);
|
||
}
|
||
|
||
let pg = ProcessManager::find_process_group(Pgid::from(*pgrp as usize));
|
||
if pg.is_none() {
|
||
return Err(SystemError::ESRCH);
|
||
} else if !Arc::ptr_eq(&pg.unwrap().session().unwrap(), ¤t.session().unwrap()) {
|
||
return Err(SystemError::EPERM);
|
||
}
|
||
|
||
ctrl.pgid = Some(Pid::from(*pgrp as usize));
|
||
|
||
return Ok(0);
|
||
}
|
||
}
|