mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 10:15:03 +00:00
Feat(tty): Supplement process group logic (#1139)
* 添加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>
This commit is contained in:
parent
f3bfe77712
commit
bc9bb9607f
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -4,7 +4,6 @@
|
|||||||
},
|
},
|
||||||
"C_Cpp.errorSquiggles": "enabled",
|
"C_Cpp.errorSquiggles": "enabled",
|
||||||
"esbonio.sphinx.confDir": "",
|
"esbonio.sphinx.confDir": "",
|
||||||
"rust-analyzer.checkOnSave.allTargets": false,
|
|
||||||
"rust-analyzer.linkedProjects": [
|
"rust-analyzer.linkedProjects": [
|
||||||
"./kernel/Cargo.toml",
|
"./kernel/Cargo.toml",
|
||||||
//"./tools/Cargo.toml",
|
//"./tools/Cargo.toml",
|
||||||
|
@ -30,4 +30,5 @@ DragonOS是一个开源项目,我们欢迎任何形式的赞助和捐赠,您
|
|||||||
财务及捐赠信息公开
|
财务及捐赠信息公开
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
DragonOS社区的捐赠信息将按年进行公开。赞助商、赞助者信息将在收到赞助后,15天内进行公开。
|
DragonOS社区的捐赠信息将按年进行公开。赞助商、赞助者信息将在收到赞助后,15天内进行公开。
|
||||||
|
|
||||||
|
@ -93,11 +93,14 @@ impl From<i32> for Signal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<SigSet> for Signal {
|
impl From<Signal> for SigSet {
|
||||||
fn into(self) -> SigSet {
|
fn from(val: Signal) -> Self {
|
||||||
self.into_sigset()
|
SigSet {
|
||||||
|
bits: (1 << (val as usize - 1) as u64),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Signal {
|
impl Signal {
|
||||||
/// 判断一个数字是否为可用的信号
|
/// 判断一个数字是否为可用的信号
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
use core::{any::Any, fmt::Debug};
|
use core::{
|
||||||
|
any::Any,
|
||||||
|
fmt::{Debug, Formatter},
|
||||||
|
};
|
||||||
|
|
||||||
use alloc::{
|
use alloc::{
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
@ -147,7 +150,6 @@ impl VirtIOBlkManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// virtio block device
|
/// virtio block device
|
||||||
#[derive(Debug)]
|
|
||||||
#[cast_to([sync] VirtIODevice)]
|
#[cast_to([sync] VirtIODevice)]
|
||||||
#[cast_to([sync] Device)]
|
#[cast_to([sync] Device)]
|
||||||
pub struct VirtIOBlkDevice {
|
pub struct VirtIOBlkDevice {
|
||||||
@ -158,6 +160,15 @@ pub struct VirtIOBlkDevice {
|
|||||||
self_ref: Weak<Self>,
|
self_ref: Weak<Self>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for VirtIOBlkDevice {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
||||||
|
f.debug_struct("VirtIOBlkDevice")
|
||||||
|
.field("devname", &self.blkdev_meta.devname)
|
||||||
|
.field("dev_id", &self.dev_id.id())
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe impl Send for VirtIOBlkDevice {}
|
unsafe impl Send for VirtIOBlkDevice {}
|
||||||
unsafe impl Sync for VirtIOBlkDevice {}
|
unsafe impl Sync for VirtIOBlkDevice {}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ pub fn virtio_console(
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
#[derive(Debug)]
|
|
||||||
#[cast_to([sync] VirtIODevice)]
|
#[cast_to([sync] VirtIODevice)]
|
||||||
#[cast_to([sync] Device)]
|
#[cast_to([sync] Device)]
|
||||||
pub struct VirtIOConsoleDevice {
|
pub struct VirtIOConsoleDevice {
|
||||||
@ -103,6 +103,22 @@ pub struct VirtIOConsoleDevice {
|
|||||||
unsafe impl Send for VirtIOConsoleDevice {}
|
unsafe impl Send for VirtIOConsoleDevice {}
|
||||||
unsafe impl Sync for VirtIOConsoleDevice {}
|
unsafe impl Sync for VirtIOConsoleDevice {}
|
||||||
|
|
||||||
|
impl Debug for VirtIOConsoleDevice {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
||||||
|
f.debug_struct("VirtIOConsoleDevice")
|
||||||
|
.field(
|
||||||
|
"devname",
|
||||||
|
&self
|
||||||
|
.dev_name
|
||||||
|
.try_get()
|
||||||
|
.map(|x| x.as_str())
|
||||||
|
.unwrap_or("uninitialized"),
|
||||||
|
)
|
||||||
|
.field("dev_id", &self.dev_id.id())
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl VirtIOConsoleDevice {
|
impl VirtIOConsoleDevice {
|
||||||
pub fn new(transport: VirtIOTransport, dev_id: Arc<DeviceId>) -> Option<Arc<Self>> {
|
pub fn new(transport: VirtIOTransport, dev_id: Arc<DeviceId>) -> Option<Arc<Self>> {
|
||||||
// 设置中断
|
// 设置中断
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use core::{
|
use core::{
|
||||||
any::Any,
|
any::Any,
|
||||||
cell::UnsafeCell,
|
cell::UnsafeCell,
|
||||||
fmt::Debug,
|
fmt::{Debug, Formatter},
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,7 +62,6 @@ fn virtio_net_driver() -> Arc<VirtIONetDriver> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// virtio net device
|
/// virtio net device
|
||||||
#[derive(Debug)]
|
|
||||||
#[cast_to([sync] VirtIODevice)]
|
#[cast_to([sync] VirtIODevice)]
|
||||||
#[cast_to([sync] Device)]
|
#[cast_to([sync] Device)]
|
||||||
pub struct VirtIONetDevice {
|
pub struct VirtIONetDevice {
|
||||||
@ -71,6 +70,14 @@ pub struct VirtIONetDevice {
|
|||||||
locked_kobj_state: LockedKObjectState,
|
locked_kobj_state: LockedKObjectState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for VirtIONetDevice {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
||||||
|
f.debug_struct("VirtIONetDevice")
|
||||||
|
.field("dev_id", &self.dev_id.id())
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe impl Send for VirtIONetDevice {}
|
unsafe impl Send for VirtIONetDevice {}
|
||||||
unsafe impl Sync for VirtIONetDevice {}
|
unsafe impl Sync for VirtIONetDevice {}
|
||||||
|
|
||||||
@ -84,7 +91,7 @@ struct InnerVirtIONetDevice {
|
|||||||
|
|
||||||
impl Debug for InnerVirtIONetDevice {
|
impl Debug for InnerVirtIONetDevice {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
f.debug_struct("InnerVirtIOBlkDevice").finish()
|
f.debug_struct("InnerVirtIONetDevice").finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,10 +44,8 @@ pub struct PosixTermios {
|
|||||||
pub c_oflag: u32,
|
pub c_oflag: u32,
|
||||||
pub c_cflag: u32,
|
pub c_cflag: u32,
|
||||||
pub c_lflag: u32,
|
pub c_lflag: u32,
|
||||||
pub c_cc: [u8; CONTORL_CHARACTER_NUM],
|
|
||||||
pub c_line: u8,
|
pub c_line: u8,
|
||||||
pub c_ispeed: u32,
|
pub c_cc: [u8; CONTORL_CHARACTER_NUM],
|
||||||
pub c_ospeed: u32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PosixTermios {
|
impl PosixTermios {
|
||||||
@ -59,8 +57,6 @@ impl PosixTermios {
|
|||||||
c_lflag: termios.local_mode.bits,
|
c_lflag: termios.local_mode.bits,
|
||||||
c_cc: termios.control_characters,
|
c_cc: termios.control_characters,
|
||||||
c_line: termios.line as u8,
|
c_line: termios.line as u8,
|
||||||
c_ispeed: termios.input_speed,
|
|
||||||
c_ospeed: termios.output_speed,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,8 +69,24 @@ impl PosixTermios {
|
|||||||
local_mode: LocalMode::from_bits_truncate(self.c_lflag),
|
local_mode: LocalMode::from_bits_truncate(self.c_lflag),
|
||||||
control_characters: self.c_cc,
|
control_characters: self.c_cc,
|
||||||
line: LineDisciplineType::from_line(self.c_line),
|
line: LineDisciplineType::from_line(self.c_line),
|
||||||
input_speed: self.c_ispeed,
|
input_speed: self.input_speed().unwrap_or(38400),
|
||||||
output_speed: self.c_ospeed,
|
output_speed: self.output_speed().unwrap_or(38400),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn output_speed(&self) -> Option<u32> {
|
||||||
|
let flag = ControlMode::from_bits_truncate(
|
||||||
|
self.c_cflag & ControlMode::CBAUD.intersection(ControlMode::CBAUDEX).bits(),
|
||||||
|
); // CBAUD + CBAUDEX
|
||||||
|
flag.baud_rate()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn input_speed(&self) -> Option<u32> {
|
||||||
|
let ibaud = (self.c_cflag & ControlMode::CIBAUD.bits()) >> 16;
|
||||||
|
if ibaud == 0 {
|
||||||
|
self.output_speed()
|
||||||
|
} else {
|
||||||
|
ControlMode::from_bits_truncate(ibaud).baud_rate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -352,6 +364,47 @@ bitflags! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ControlMode {
|
||||||
|
/// 获取波特率
|
||||||
|
pub fn baud_rate(&self) -> Option<u32> {
|
||||||
|
let flag = self.intersection(Self::CBAUD);
|
||||||
|
match flag {
|
||||||
|
Self::B0 => Some(0),
|
||||||
|
Self::B50 => Some(50),
|
||||||
|
Self::B75 => Some(75),
|
||||||
|
Self::B110 => Some(110),
|
||||||
|
Self::B134 => Some(134),
|
||||||
|
Self::B150 => Some(150),
|
||||||
|
Self::B200 => Some(200),
|
||||||
|
Self::B300 => Some(300),
|
||||||
|
Self::B600 => Some(600),
|
||||||
|
Self::B1200 => Some(1200),
|
||||||
|
Self::B1800 => Some(1800),
|
||||||
|
Self::B2400 => Some(2400),
|
||||||
|
Self::B4800 => Some(4800),
|
||||||
|
Self::B9600 => Some(9600),
|
||||||
|
Self::B19200 => Some(19200),
|
||||||
|
Self::B38400 => Some(38400),
|
||||||
|
Self::B57600 => Some(57600),
|
||||||
|
Self::B115200 => Some(115200),
|
||||||
|
Self::B230400 => Some(230400),
|
||||||
|
Self::B460800 => Some(460800),
|
||||||
|
Self::B500000 => Some(500000),
|
||||||
|
Self::B576000 => Some(576000),
|
||||||
|
Self::B921600 => Some(921600),
|
||||||
|
Self::B1000000 => Some(1000000),
|
||||||
|
Self::B1152000 => Some(1152000),
|
||||||
|
Self::B1500000 => Some(1500000),
|
||||||
|
Self::B2000000 => Some(2000000),
|
||||||
|
Self::B2500000 => Some(2500000),
|
||||||
|
Self::B3000000 => Some(3000000),
|
||||||
|
Self::B3500000 => Some(3500000),
|
||||||
|
Self::B4000000 => Some(4000000),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 对应termios中控制字符的索引
|
/// 对应termios中控制字符的索引
|
||||||
pub struct ControlCharIndex;
|
pub struct ControlCharIndex;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -19,7 +19,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
mm::VirtAddr,
|
mm::VirtAddr,
|
||||||
net::event_poll::{EPollEventType, EPollItem},
|
net::event_poll::{EPollEventType, EPollItem},
|
||||||
process::Pid,
|
process::{process_group::Pgid, session::Sid, ProcessControlBlock},
|
||||||
syscall::user_access::{UserBufferReader, UserBufferWriter},
|
syscall::user_access::{UserBufferReader, UserBufferWriter},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -280,16 +280,23 @@ impl TtyCore {
|
|||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct TtyContorlInfo {
|
pub struct TtyContorlInfo {
|
||||||
/// 前台进程pid
|
/// 当前会话的SId
|
||||||
pub session: Option<Pid>,
|
pub session: Option<Sid>,
|
||||||
/// 前台进程组id
|
/// 前台进程组id
|
||||||
pub pgid: Option<Pid>,
|
pub pgid: Option<Pgid>,
|
||||||
|
|
||||||
/// packet模式下使用,目前未用到
|
/// packet模式下使用,目前未用到
|
||||||
pub pktstatus: TtyPacketStatus,
|
pub pktstatus: TtyPacketStatus,
|
||||||
pub packet: bool,
|
pub packet: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TtyContorlInfo {
|
||||||
|
pub fn set_info_by_pcb(&mut self, pcb: Arc<ProcessControlBlock>) {
|
||||||
|
self.session = Some(pcb.sid());
|
||||||
|
self.pgid = Some(pcb.pgid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct TtyFlowState {
|
pub struct TtyFlowState {
|
||||||
/// 表示流控是否被停止
|
/// 表示流控是否被停止
|
||||||
|
@ -4,7 +4,7 @@ use system_error::SystemError;
|
|||||||
use crate::{
|
use crate::{
|
||||||
arch::ipc::signal::{SigSet, Signal},
|
arch::ipc::signal::{SigSet, Signal},
|
||||||
mm::VirtAddr,
|
mm::VirtAddr,
|
||||||
process::{Pid, ProcessFlags, ProcessManager},
|
process::{process_group::Pgid, Pid, ProcessFlags, ProcessManager},
|
||||||
syscall::{
|
syscall::{
|
||||||
user_access::{UserBufferReader, UserBufferWriter},
|
user_access::{UserBufferReader, UserBufferWriter},
|
||||||
Syscall,
|
Syscall,
|
||||||
@ -19,16 +19,13 @@ impl TtyJobCtrlManager {
|
|||||||
/// ### 设置当前进程的tty
|
/// ### 设置当前进程的tty
|
||||||
pub fn proc_set_tty(tty: Arc<TtyCore>) {
|
pub fn proc_set_tty(tty: Arc<TtyCore>) {
|
||||||
let core = tty.core();
|
let core = tty.core();
|
||||||
let mut ctrl = core.contorl_info_irqsave();
|
|
||||||
let pcb = ProcessManager::current_pcb();
|
let pcb = ProcessManager::current_pcb();
|
||||||
|
|
||||||
let pid = Pid::new(pcb.basic().sid().into());
|
let mut ctrl = core.contorl_info_irqsave();
|
||||||
ctrl.session = Some(pid);
|
ctrl.set_info_by_pcb(pcb.clone());
|
||||||
|
drop(ctrl);
|
||||||
assert!(pcb.sig_info_irqsave().tty().is_none());
|
|
||||||
|
|
||||||
let mut singal = pcb.sig_info_mut();
|
let mut singal = pcb.sig_info_mut();
|
||||||
drop(ctrl);
|
|
||||||
singal.set_tty(Some(tty.clone()));
|
singal.set_tty(Some(tty.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,27 +39,27 @@ impl TtyJobCtrlManager {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let core = tty.core();
|
let pgid = pcb.pgid();
|
||||||
let ctrl = core.contorl_info_irqsave();
|
|
||||||
|
|
||||||
// todo pgid
|
let ctrl = tty.core().contorl_info_irqsave();
|
||||||
let pgid = pcb.pid();
|
|
||||||
let tty_pgid = ctrl.pgid;
|
let tty_pgid = ctrl.pgid;
|
||||||
|
drop(ctrl);
|
||||||
|
|
||||||
if tty_pgid.is_some() && tty_pgid.unwrap() != pgid {
|
if tty_pgid.is_some() && tty_pgid.unwrap() != pgid {
|
||||||
if pcb
|
if pcb
|
||||||
.sig_info_irqsave()
|
.sig_info_irqsave()
|
||||||
.sig_blocked()
|
.sig_blocked()
|
||||||
.contains(SigSet::from_bits_truncate(1 << sig as u64))
|
.contains(SigSet::from(sig))
|
||||||
|| pcb.sig_struct_irqsave().handlers[sig as usize - 1].is_ignore()
|
|| pcb.sig_struct_irqsave().handlers[sig as usize - 1].is_ignore()
|
||||||
{
|
{
|
||||||
// 忽略该信号
|
// 忽略该信号
|
||||||
if sig == Signal::SIGTTIN {
|
if sig == Signal::SIGTTIN {
|
||||||
return Err(SystemError::EIO);
|
return Err(SystemError::EIO);
|
||||||
}
|
}
|
||||||
|
} else if ProcessManager::is_current_pgrp_orphaned() {
|
||||||
|
return Err(SystemError::EIO);
|
||||||
} else {
|
} else {
|
||||||
// 暂时使用kill而不是killpg
|
Syscall::kill_process_group(pgid, sig)?;
|
||||||
Syscall::kill_process(pgid, sig)?;
|
|
||||||
ProcessManager::current_pcb()
|
ProcessManager::current_pcb()
|
||||||
.flags()
|
.flags()
|
||||||
.insert(ProcessFlags::HAS_PENDING_SIGNAL);
|
.insert(ProcessFlags::HAS_PENDING_SIGNAL);
|
||||||
@ -74,74 +71,146 @@ impl TtyJobCtrlManager {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn job_ctrl_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> {
|
pub fn job_ctrl_ioctl(
|
||||||
|
real_tty: Arc<TtyCore>,
|
||||||
|
cmd: u32,
|
||||||
|
arg: usize,
|
||||||
|
) -> Result<usize, SystemError> {
|
||||||
match cmd {
|
match cmd {
|
||||||
TtyIoctlCmd::TIOCSPGRP => {
|
TtyIoctlCmd::TIOCSPGRP => Self::tiocspgrp(real_tty, arg),
|
||||||
match Self::tty_check_change(tty.clone(), Signal::SIGTTOU) {
|
TtyIoctlCmd::TIOCGPGRP => Self::tiocgpgrp(real_tty, arg),
|
||||||
Ok(_) => {}
|
TtyIoctlCmd::TIOCGSID => Self::tiocgsid(real_tty, arg),
|
||||||
Err(e) => {
|
TtyIoctlCmd::TIOCSCTTY => Self::tiocsctty(real_tty),
|
||||||
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 = tty.core().contorl_info_irqsave();
|
|
||||||
|
|
||||||
if current.sig_info_irqsave().tty().is_none()
|
|
||||||
|| !Arc::ptr_eq(¤t.sig_info_irqsave().tty().clone().unwrap(), &tty)
|
|
||||||
|| ctrl.session.is_none()
|
|
||||||
|| ctrl.session.unwrap() != Pid::from(current.basic().sid().into())
|
|
||||||
{
|
|
||||||
return Err(SystemError::ENOTTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctrl.pgid = Some(Pid::from(*pgrp as usize));
|
|
||||||
|
|
||||||
return Ok(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TtyIoctlCmd::TIOCGPGRP => {
|
|
||||||
let current = ProcessManager::current_pcb();
|
|
||||||
if current.sig_info_irqsave().tty().is_some()
|
|
||||||
&& !Arc::ptr_eq(¤t.sig_info_irqsave().tty().unwrap(), &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(
|
|
||||||
&(tty
|
|
||||||
.core()
|
|
||||||
.contorl_info_irqsave()
|
|
||||||
.pgid
|
|
||||||
.unwrap_or(Pid::new(0))
|
|
||||||
.data() as i32),
|
|
||||||
0,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
return Ok(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(SystemError::ENOIOCTLCMD);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -390,7 +390,7 @@ impl NTtyData {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((c as usize) < self.char_map.size()) && self.char_map.get(c as usize).unwrap() {
|
if ((c as usize) < self.char_map.len()) && self.char_map.get(c as usize).unwrap() {
|
||||||
// 特殊字符
|
// 特殊字符
|
||||||
self.receive_special_char(c, tty.clone(), lookahead_done);
|
self.receive_special_char(c, tty.clone(), lookahead_done);
|
||||||
} else {
|
} else {
|
||||||
@ -790,7 +790,7 @@ impl NTtyData {
|
|||||||
let ctrl_info = tty.core().contorl_info_irqsave();
|
let ctrl_info = tty.core().contorl_info_irqsave();
|
||||||
let pg = ctrl_info.pgid;
|
let pg = ctrl_info.pgid;
|
||||||
if let Some(pg) = pg {
|
if let Some(pg) = pg {
|
||||||
let _ = Syscall::kill_process(pg, signal);
|
let _ = Syscall::kill_process_group(pg, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !termios.local_mode.contains(LocalMode::NOFLSH) {
|
if !termios.local_mode.contains(LocalMode::NOFLSH) {
|
||||||
|
@ -50,6 +50,8 @@ pub enum ProcFileType {
|
|||||||
ProcMeminfo = 1,
|
ProcMeminfo = 1,
|
||||||
/// kmsg
|
/// kmsg
|
||||||
ProcKmsg = 2,
|
ProcKmsg = 2,
|
||||||
|
/// 可执行路径
|
||||||
|
ProcExe = 3,
|
||||||
//todo: 其他文件类型
|
//todo: 其他文件类型
|
||||||
///默认文件类型
|
///默认文件类型
|
||||||
Default,
|
Default,
|
||||||
@ -61,6 +63,7 @@ impl From<u8> for ProcFileType {
|
|||||||
0 => ProcFileType::ProcStatus,
|
0 => ProcFileType::ProcStatus,
|
||||||
1 => ProcFileType::ProcMeminfo,
|
1 => ProcFileType::ProcMeminfo,
|
||||||
2 => ProcFileType::ProcKmsg,
|
2 => ProcFileType::ProcKmsg,
|
||||||
|
3 => ProcFileType::ProcExe,
|
||||||
_ => ProcFileType::Default,
|
_ => ProcFileType::Default,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -266,6 +269,28 @@ impl ProcFSInode {
|
|||||||
return Ok((data.len() * size_of::<u8>()) as i64);
|
return Ok((data.len() * size_of::<u8>()) as i64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 打开 exe 文件
|
||||||
|
fn open_exe(&self, _pdata: &mut ProcfsFilePrivateData) -> Result<i64, SystemError> {
|
||||||
|
// 这个文件是一个软链接,直接返回0即可
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取exe文件
|
||||||
|
fn read_link(&self, buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||||
|
// 判断是否有记录pid信息,有的话就是当前进程的exe文件,没有则是当前进程的exe文件
|
||||||
|
let pid = self.fdata.pid;
|
||||||
|
let pcb = if pid == Pid::from(0) {
|
||||||
|
ProcessManager::current_pcb()
|
||||||
|
} else {
|
||||||
|
ProcessManager::find(pid).ok_or(SystemError::ESRCH)?
|
||||||
|
};
|
||||||
|
let exe = pcb.execute_path();
|
||||||
|
let exe_bytes = exe.as_bytes();
|
||||||
|
let len = exe_bytes.len().min(buf.len());
|
||||||
|
buf[..len].copy_from_slice(&exe_bytes[..len]);
|
||||||
|
Ok(len)
|
||||||
|
}
|
||||||
|
|
||||||
/// proc文件系统读取函数
|
/// proc文件系统读取函数
|
||||||
fn proc_read(
|
fn proc_read(
|
||||||
&self,
|
&self,
|
||||||
@ -419,6 +444,23 @@ impl ProcFS {
|
|||||||
} else {
|
} else {
|
||||||
panic!("create version_signature error");
|
panic!("create version_signature error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let self_dir = inode
|
||||||
|
.create("self", FileType::Dir, ModeType::from_bits_truncate(0o555))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let binding = self_dir.create("exe", FileType::SymLink, ModeType::S_IRUGO);
|
||||||
|
if let Ok(exe) = binding {
|
||||||
|
let exe_file = exe
|
||||||
|
.as_any_ref()
|
||||||
|
.downcast_ref::<LockedProcFSInode>()
|
||||||
|
.unwrap();
|
||||||
|
exe_file.0.lock().fdata.pid = Pid::new(0);
|
||||||
|
exe_file.0.lock().fdata.ftype = ProcFileType::ProcExe;
|
||||||
|
} else {
|
||||||
|
panic!("create exe error");
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,18 +477,32 @@ impl ProcFS {
|
|||||||
)?;
|
)?;
|
||||||
// 创建相关文件
|
// 创建相关文件
|
||||||
// status文件
|
// status文件
|
||||||
let binding: Arc<dyn IndexNode> = pid_dir.create(
|
let status_binding: Arc<dyn IndexNode> = pid_dir.create(
|
||||||
"status",
|
"status",
|
||||||
FileType::File,
|
FileType::File,
|
||||||
ModeType::from_bits_truncate(0o444),
|
ModeType::from_bits_truncate(0o444),
|
||||||
)?;
|
)?;
|
||||||
let status_file: &LockedProcFSInode = binding
|
let status_file: &LockedProcFSInode = status_binding
|
||||||
.as_any_ref()
|
.as_any_ref()
|
||||||
.downcast_ref::<LockedProcFSInode>()
|
.downcast_ref::<LockedProcFSInode>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
status_file.0.lock().fdata.pid = pid;
|
status_file.0.lock().fdata.pid = pid;
|
||||||
status_file.0.lock().fdata.ftype = ProcFileType::ProcStatus;
|
status_file.0.lock().fdata.ftype = ProcFileType::ProcStatus;
|
||||||
|
|
||||||
|
// exe文件
|
||||||
|
let exe_binding: Arc<dyn IndexNode> = pid_dir.create_with_data(
|
||||||
|
"exe",
|
||||||
|
FileType::SymLink,
|
||||||
|
ModeType::from_bits_truncate(0o444),
|
||||||
|
0,
|
||||||
|
)?;
|
||||||
|
let exe_file = exe_binding
|
||||||
|
.as_any_ref()
|
||||||
|
.downcast_ref::<LockedProcFSInode>()
|
||||||
|
.unwrap();
|
||||||
|
exe_file.0.lock().fdata.pid = pid;
|
||||||
|
exe_file.0.lock().fdata.ftype = ProcFileType::ProcExe;
|
||||||
|
|
||||||
//todo: 创建其他文件
|
//todo: 创建其他文件
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -461,6 +517,7 @@ impl ProcFS {
|
|||||||
let pid_dir: Arc<dyn IndexNode> = proc.find(&pid.to_string())?;
|
let pid_dir: Arc<dyn IndexNode> = proc.find(&pid.to_string())?;
|
||||||
// 删除进程文件夹下文件
|
// 删除进程文件夹下文件
|
||||||
pid_dir.unlink("status")?;
|
pid_dir.unlink("status")?;
|
||||||
|
pid_dir.unlink("exe")?;
|
||||||
|
|
||||||
// 查看进程文件是否还存在
|
// 查看进程文件是否还存在
|
||||||
// let pf= pid_dir.find("status").expect("Cannot find status");
|
// let pf= pid_dir.find("status").expect("Cannot find status");
|
||||||
@ -490,6 +547,7 @@ impl IndexNode for LockedProcFSInode {
|
|||||||
let file_size = match inode.fdata.ftype {
|
let file_size = match inode.fdata.ftype {
|
||||||
ProcFileType::ProcStatus => inode.open_status(&mut private_data)?,
|
ProcFileType::ProcStatus => inode.open_status(&mut private_data)?,
|
||||||
ProcFileType::ProcMeminfo => inode.open_meminfo(&mut private_data)?,
|
ProcFileType::ProcMeminfo => inode.open_meminfo(&mut private_data)?,
|
||||||
|
ProcFileType::ProcExe => inode.open_exe(&mut private_data)?,
|
||||||
ProcFileType::Default => inode.data.len() as i64,
|
ProcFileType::Default => inode.data.len() as i64,
|
||||||
_ => {
|
_ => {
|
||||||
todo!()
|
todo!()
|
||||||
@ -548,6 +606,7 @@ impl IndexNode for LockedProcFSInode {
|
|||||||
ProcFileType::ProcMeminfo => {
|
ProcFileType::ProcMeminfo => {
|
||||||
return inode.proc_read(offset, len, buf, &mut private_data)
|
return inode.proc_read(offset, len, buf, &mut private_data)
|
||||||
}
|
}
|
||||||
|
ProcFileType::ProcExe => return inode.read_link(buf),
|
||||||
ProcFileType::ProcKmsg => (),
|
ProcFileType::ProcKmsg => (),
|
||||||
ProcFileType::Default => (),
|
ProcFileType::Default => (),
|
||||||
};
|
};
|
||||||
|
@ -24,9 +24,9 @@ use super::{cmdline::kenrel_cmdline_param_manager, initcall::do_initcalls};
|
|||||||
|
|
||||||
const INIT_PROC_TRYLIST: [(&str, Option<&str>); 4] = [
|
const INIT_PROC_TRYLIST: [(&str, Option<&str>); 4] = [
|
||||||
("/bin/dragonreach", None),
|
("/bin/dragonreach", None),
|
||||||
|
("/bin/busybox", Some("init")),
|
||||||
("/bin/init", None),
|
("/bin/init", None),
|
||||||
("/bin/sh", None),
|
("/bin/sh", None),
|
||||||
("/bin/busybox", Some("init")),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn initial_kernel_thread() -> i32 {
|
pub fn initial_kernel_thread() -> i32 {
|
||||||
|
@ -310,13 +310,21 @@ impl ProcessManager {
|
|||||||
current_pcb: &Arc<ProcessControlBlock>,
|
current_pcb: &Arc<ProcessControlBlock>,
|
||||||
new_pcb: &Arc<ProcessControlBlock>,
|
new_pcb: &Arc<ProcessControlBlock>,
|
||||||
) -> Result<(), SystemError> {
|
) -> Result<(), SystemError> {
|
||||||
// // 将信号的处理函数设置为default(除了那些被手动屏蔽的)
|
// todo SignalStruct结构需要更改,属于线程组逻辑
|
||||||
if clone_flags.contains(CloneFlags::CLONE_CLEAR_SIGHAND) {
|
if clone_flags.contains(CloneFlags::CLONE_SIGHAND) {
|
||||||
flush_signal_handlers(new_pcb.clone(), false);
|
// log::debug!("copy_sighand: CLONE_SIGHAND");
|
||||||
|
current_pcb
|
||||||
|
.sig_struct_irqsave()
|
||||||
|
.cnt
|
||||||
|
.fetch_add(1, Ordering::SeqCst);
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if clone_flags.contains(CloneFlags::CLONE_SIGHAND) {
|
// log::debug!("Just copy sighand");
|
||||||
new_pcb.sig_struct_irqsave().handlers = current_pcb.sig_struct_irqsave().handlers;
|
new_pcb.sig_struct_irqsave().handlers = current_pcb.sig_struct_irqsave().handlers;
|
||||||
|
|
||||||
|
if clone_flags.contains(CloneFlags::CLONE_CLEAR_SIGHAND) {
|
||||||
|
flush_signal_handlers(new_pcb.clone(), false);
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -587,15 +595,6 @@ impl ProcessManager {
|
|||||||
|
|
||||||
child_pcb.set_process_group(&pg);
|
child_pcb.set_process_group(&pg);
|
||||||
|
|
||||||
let mut guard = child_pcb.basic_mut();
|
|
||||||
guard.set_pgid(pg.pgid());
|
|
||||||
drop(guard);
|
|
||||||
//todo 这里应该解除注释,但是每次一到这里就触发调度,然后由于当前进程持有锁的数量不等于0导致panic
|
|
||||||
//
|
|
||||||
// if let Some(session) = pg.session() {
|
|
||||||
// guard.set_sid(session.sid());
|
|
||||||
// }
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -737,6 +737,9 @@ pub struct ProcessControlBlock {
|
|||||||
|
|
||||||
/// 进程组
|
/// 进程组
|
||||||
process_group: Mutex<Weak<ProcessGroup>>,
|
process_group: Mutex<Weak<ProcessGroup>>,
|
||||||
|
|
||||||
|
/// 进程的可执行文件路径
|
||||||
|
executable_path: RwLock<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProcessControlBlock {
|
impl ProcessControlBlock {
|
||||||
@ -788,14 +791,7 @@ impl ProcessControlBlock {
|
|||||||
(Self::generate_pid(), ppid, cwd, cred, tty)
|
(Self::generate_pid(), ppid, cwd, cred, tty)
|
||||||
};
|
};
|
||||||
|
|
||||||
let basic_info = ProcessBasicInfo::new(
|
let basic_info = ProcessBasicInfo::new(ppid, name.clone(), cwd, None);
|
||||||
Pgid::from(pid.into()),
|
|
||||||
ppid,
|
|
||||||
Sid::from(pid.into()),
|
|
||||||
name,
|
|
||||||
cwd,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
let preempt_count = AtomicUsize::new(0);
|
let preempt_count = AtomicUsize::new(0);
|
||||||
let flags = unsafe { LockFreeFlags::new(ProcessFlags::empty()) };
|
let flags = unsafe { LockFreeFlags::new(ProcessFlags::empty()) };
|
||||||
|
|
||||||
@ -833,6 +829,7 @@ impl ProcessControlBlock {
|
|||||||
self_ref: Weak::new(),
|
self_ref: Weak::new(),
|
||||||
restart_block: SpinLock::new(None),
|
restart_block: SpinLock::new(None),
|
||||||
process_group: Mutex::new(Weak::new()),
|
process_group: Mutex::new(Weak::new()),
|
||||||
|
executable_path: RwLock::new(name),
|
||||||
};
|
};
|
||||||
|
|
||||||
pcb.sig_info.write().set_tty(tty);
|
pcb.sig_info.write().set_tty(tty);
|
||||||
@ -1030,6 +1027,14 @@ impl ProcessControlBlock {
|
|||||||
self.cred.lock().clone()
|
self.cred.lock().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_execute_path(&self, path: String) {
|
||||||
|
*self.executable_path.write() = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn execute_path(&self) -> String {
|
||||||
|
self.executable_path.read().clone()
|
||||||
|
}
|
||||||
|
|
||||||
/// 根据文件描述符序号,获取socket对象的Arc指针
|
/// 根据文件描述符序号,获取socket对象的Arc指针
|
||||||
///
|
///
|
||||||
/// ## 参数
|
/// ## 参数
|
||||||
@ -1206,6 +1211,17 @@ impl ProcessControlBlock {
|
|||||||
*self.restart_block.lock() = restart_block;
|
*self.restart_block.lock() = restart_block;
|
||||||
return Err(SystemError::ERESTART_RESTARTBLOCK);
|
return Err(SystemError::ERESTART_RESTARTBLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parent_pcb(&self) -> Option<Arc<ProcessControlBlock>> {
|
||||||
|
self.parent_pcb.read().upgrade()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_exited(&self) -> bool {
|
||||||
|
self.sched_info
|
||||||
|
.inner_lock_read_irqsave()
|
||||||
|
.state()
|
||||||
|
.is_exited()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for ProcessControlBlock {
|
impl Drop for ProcessControlBlock {
|
||||||
@ -1264,12 +1280,8 @@ impl ThreadInfo {
|
|||||||
/// 这个结构体保存进程的基本信息,主要是那些不会随着进程的运行而经常改变的信息。
|
/// 这个结构体保存进程的基本信息,主要是那些不会随着进程的运行而经常改变的信息。
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ProcessBasicInfo {
|
pub struct ProcessBasicInfo {
|
||||||
/// 当前进程的进程组id
|
|
||||||
pgid: Pgid,
|
|
||||||
/// 当前进程的父进程的pid
|
/// 当前进程的父进程的pid
|
||||||
ppid: Pid,
|
ppid: Pid,
|
||||||
/// 当前进程所属会话id
|
|
||||||
sid: Sid,
|
|
||||||
/// 进程的名字
|
/// 进程的名字
|
||||||
name: String,
|
name: String,
|
||||||
|
|
||||||
@ -1286,18 +1298,14 @@ pub struct ProcessBasicInfo {
|
|||||||
impl ProcessBasicInfo {
|
impl ProcessBasicInfo {
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
pgid: Pgid,
|
|
||||||
ppid: Pid,
|
ppid: Pid,
|
||||||
sid: Sid,
|
|
||||||
name: String,
|
name: String,
|
||||||
cwd: String,
|
cwd: String,
|
||||||
user_vm: Option<Arc<AddressSpace>>,
|
user_vm: Option<Arc<AddressSpace>>,
|
||||||
) -> RwLock<Self> {
|
) -> RwLock<Self> {
|
||||||
let fd_table = Arc::new(RwLock::new(FileDescriptorVec::new()));
|
let fd_table = Arc::new(RwLock::new(FileDescriptorVec::new()));
|
||||||
return RwLock::new(Self {
|
return RwLock::new(Self {
|
||||||
pgid,
|
|
||||||
ppid,
|
ppid,
|
||||||
sid,
|
|
||||||
name,
|
name,
|
||||||
cwd,
|
cwd,
|
||||||
user_vm,
|
user_vm,
|
||||||
@ -1305,26 +1313,10 @@ impl ProcessBasicInfo {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pgid(&self) -> Pgid {
|
|
||||||
return self.pgid;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_pgid(&mut self, pgid: Pgid) {
|
|
||||||
self.pgid = pgid;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ppid(&self) -> Pid {
|
pub fn ppid(&self) -> Pid {
|
||||||
return self.ppid;
|
return self.ppid;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sid(&self) -> Sid {
|
|
||||||
return self.sid;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_sid(&mut self, sid: Sid) {
|
|
||||||
self.sid = sid;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
return &self.name;
|
return &self.name;
|
||||||
}
|
}
|
||||||
|
@ -171,6 +171,29 @@ impl ProcessManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/exit.c#345
|
||||||
|
pub fn is_current_pgrp_orphaned() -> bool {
|
||||||
|
let current_pcb = ProcessManager::current_pcb();
|
||||||
|
let sid = current_pcb.sid();
|
||||||
|
let process_group = current_pcb.process_group();
|
||||||
|
if let Some(pg) = process_group {
|
||||||
|
for process in pg.process_group_inner.lock().processes.values() {
|
||||||
|
if let Some(real_parent) = process.real_parent_pcb.read().clone().upgrade() {
|
||||||
|
//todo 添加判断: 1.是否被忽略 2.是否已经退出(线程组是否为空)
|
||||||
|
if real_parent.pid == Pid(1) || process.is_exited() {
|
||||||
|
log::debug!("is_current_pgrp_orphaned: real_parent is init or exited");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let real_parent_pg = real_parent.process_group().unwrap();
|
||||||
|
if real_parent_pg.pgid() != pg.pgid() && real_parent_pg.sid() == sid {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProcessControlBlock {
|
impl ProcessControlBlock {
|
||||||
|
@ -215,6 +215,6 @@ impl ProcessControlBlock {
|
|||||||
if let Some(session) = self.session() {
|
if let Some(session) = self.session() {
|
||||||
return session.sid();
|
return session.sid();
|
||||||
}
|
}
|
||||||
return Sid::new(0);
|
return Sid::new(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,15 +139,17 @@ impl Syscall {
|
|||||||
.basic_mut()
|
.basic_mut()
|
||||||
.set_name(ProcessControlBlock::generate_name(&path, &argv));
|
.set_name(ProcessControlBlock::generate_name(&path, &argv));
|
||||||
|
|
||||||
Self::do_execve(path, argv, envp, frame)?;
|
Self::do_execve(path.clone(), argv, envp, frame)?;
|
||||||
|
|
||||||
|
let pcb = ProcessManager::current_pcb();
|
||||||
// 关闭设置了O_CLOEXEC的文件描述符
|
// 关闭设置了O_CLOEXEC的文件描述符
|
||||||
let fd_table = ProcessManager::current_pcb().fd_table();
|
let fd_table = pcb.fd_table();
|
||||||
fd_table.write().close_on_exec();
|
fd_table.write().close_on_exec();
|
||||||
// debug!(
|
// debug!(
|
||||||
// "after execve: strong count: {}",
|
// "after execve: strong count: {}",
|
||||||
// Arc::strong_count(&ProcessManager::current_pcb())
|
// Arc::strong_count(&ProcessManager::current_pcb())
|
||||||
// );
|
// );
|
||||||
|
pcb.set_execute_path(path);
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -311,6 +313,8 @@ impl Syscall {
|
|||||||
pub fn setsid() -> Result<usize, SystemError> {
|
pub fn setsid() -> Result<usize, SystemError> {
|
||||||
let pcb = ProcessManager::current_pcb();
|
let pcb = ProcessManager::current_pcb();
|
||||||
let session = pcb.go_to_new_session()?;
|
let session = pcb.go_to_new_session()?;
|
||||||
|
let mut guard = pcb.sig_info_mut();
|
||||||
|
guard.set_tty(None);
|
||||||
Ok(session.sid().into())
|
Ok(session.sid().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1236,6 +1236,10 @@ impl Syscall {
|
|||||||
SYS_SETRLIMIT => Ok(0),
|
SYS_SETRLIMIT => Ok(0),
|
||||||
SYS_RESTART_SYSCALL => Self::restart_syscall(),
|
SYS_RESTART_SYSCALL => Self::restart_syscall(),
|
||||||
SYS_RT_SIGPENDING => Self::rt_sigpending(args[0], args[1]),
|
SYS_RT_SIGPENDING => Self::rt_sigpending(args[0], args[1]),
|
||||||
|
SYS_RT_SIGTIMEDWAIT => {
|
||||||
|
log::warn!("SYS_RT_SIGTIMEDWAIT has not yet been implemented");
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
_ => panic!("Unsupported syscall ID: {}", syscall_num),
|
_ => panic!("Unsupported syscall ID: {}", syscall_num),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
3
user/apps/busybox/.gitignore
vendored
Normal file
3
user/apps/busybox/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
build/
|
||||||
|
busybox-1.35.0.tar.bz2
|
||||||
|
busybox-1.35.0.tar.bz2.md5sum
|
76
user/apps/busybox/Makefile
Normal file
76
user/apps/busybox/Makefile
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
ARCH ?= x86_64
|
||||||
|
busybox_version := 1.35.0
|
||||||
|
busybox_tarball := busybox-$(busybox_version).tar.bz2
|
||||||
|
busybox_tarball_path := $(busybox_tarball)
|
||||||
|
build_dir := build/$(ARCH)
|
||||||
|
busybox_dir := $(build_dir)/busybox-$(busybox_version)
|
||||||
|
prefix := $(ARCH)-linux-musl-
|
||||||
|
bin := build/$(ARCH)/busybox
|
||||||
|
|
||||||
|
# 特殊架构处理
|
||||||
|
ifeq ($(ARCH), mipsel)
|
||||||
|
prefix := mipsel-linux-musln32-
|
||||||
|
endif
|
||||||
|
|
||||||
|
cc := $(prefix)gcc
|
||||||
|
strip := $(prefix)strip
|
||||||
|
|
||||||
|
# 下载 busybox 的 md5sum 文件
|
||||||
|
$(busybox_tarball_path).md5sum:
|
||||||
|
wget https://mirrors.dragonos.org.cn/pub/third_party/busybox/$(busybox_tarball).md5sum
|
||||||
|
|
||||||
|
# 下载源码
|
||||||
|
$(busybox_tarball_path): $(busybox_tarball_path).md5sum
|
||||||
|
@if [ ! -f $@ ] || ! md5sum -c $(busybox_tarball_path).md5sum; then \
|
||||||
|
echo "Downloading $@..."; \
|
||||||
|
wget https://mirrors.dragonos.org.cn/pub/third_party/busybox/$(busybox_tarball); \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 解压源码包
|
||||||
|
$(busybox_dir): $(busybox_tarball_path)
|
||||||
|
mkdir -p $(build_dir)
|
||||||
|
tar -xjf $< -C $(build_dir)
|
||||||
|
|
||||||
|
# 配置和编译
|
||||||
|
$(bin): $(busybox_dir)
|
||||||
|
@# 应用必要补丁和配置调整
|
||||||
|
cd $(busybox_dir) && \
|
||||||
|
make defconfig && \
|
||||||
|
sed -i '/CONFIG_STATIC/s/.*/CONFIG_STATIC=y/' .config && \
|
||||||
|
sed -i '/CONFIG_PIE/d' .config && \
|
||||||
|
sed -i '/CONFIG_FEATURE_EDITING/s/=y/=n/' .config && \
|
||||||
|
sed -i '/CONFIG_HUSH/s/=y/=n/' .config && \
|
||||||
|
sed -i '/CONFIG_NOMMU/s/=y/=n/' .config && \
|
||||||
|
echo "CONFIG_CROSS_COMPILER_PREFIX=\"$(prefix)\"" >> .config && \
|
||||||
|
echo "CONFIG_FEATURE_STATIC=y" >> .config && \
|
||||||
|
echo "CONFIG_STATIC_LIBGCC=y" >> .config && \
|
||||||
|
echo "CONFIG_ASH=y" >> .config && \
|
||||||
|
echo "CONFIG_ASH_READ_PROFILE=y" >> .config && \
|
||||||
|
echo "CONFIG_FEATURE_EDITING=y" >> .config && \
|
||||||
|
echo "CONFIG_HUSH=y" >> .config
|
||||||
|
|
||||||
|
@# 执行编译
|
||||||
|
cd $(busybox_dir) && \
|
||||||
|
KCONFIG_NOTIMESTAMP=1 make CC="$(cc)" CFLAGS_EXTRA="-static -Os" LDFLAGS="--static" -j$(nproc)
|
||||||
|
|
||||||
|
@# 处理编译输出
|
||||||
|
mkdir -p $(dir $(bin))
|
||||||
|
cp $(busybox_dir)/busybox $(bin)
|
||||||
|
$(strip) $(bin)
|
||||||
|
|
||||||
|
.PHONY: all clean menuconfig
|
||||||
|
|
||||||
|
all: $(bin)
|
||||||
|
|
||||||
|
install: all
|
||||||
|
mv $(bin) $(DADK_CURRENT_BUILD_DIR)/busybox
|
||||||
|
|
||||||
|
# 交互式配置菜单
|
||||||
|
menuconfig: $(busybox_dir)
|
||||||
|
cd $(busybox_dir) && make menuconfig
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf build/
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f $(busybox_tarball_path) $(busybox_tarball_path).md5sum
|
36
user/dadk/config/busybox_1_35_0.toml
Normal file
36
user/dadk/config/busybox_1_35_0.toml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# 用户程序名称
|
||||||
|
name = "busybox"
|
||||||
|
# 版本号
|
||||||
|
version = "1.35.0"
|
||||||
|
# 用户程序描述信息
|
||||||
|
description = ""
|
||||||
|
# (可选)是否只构建一次,如果为true,DADK会在构建成功后,将构建结果缓存起来,下次构建时,直接使用缓存的构建结果
|
||||||
|
build-once = false
|
||||||
|
# (可选) 是否只安装一次,如果为true,DADK会在安装成功后,不再重复安装
|
||||||
|
install-once = false
|
||||||
|
# 目标架构
|
||||||
|
# 可选值:"x86_64", "aarch64", "riscv64"
|
||||||
|
target-arch = ["x86_64"]
|
||||||
|
# 任务源
|
||||||
|
[task-source]
|
||||||
|
# 构建类型
|
||||||
|
# 可选值:"build-from_source", "install-from-prebuilt"
|
||||||
|
type = "build-from-source"
|
||||||
|
# 构建来源
|
||||||
|
# "build_from_source" 可选值:"git", "local", "archive"
|
||||||
|
# "install_from_prebuilt" 可选值:"local", "archive"
|
||||||
|
source = "local"
|
||||||
|
# 路径或URL
|
||||||
|
source-path = "user/apps/busybox"
|
||||||
|
# 构建相关信息
|
||||||
|
[build]
|
||||||
|
# (可选)构建命令
|
||||||
|
build-command = "make install"
|
||||||
|
# 安装相关信息
|
||||||
|
[install]
|
||||||
|
# (可选)安装到DragonOS的路径
|
||||||
|
in-dragonos-path = "/bin"
|
||||||
|
# 清除相关信息
|
||||||
|
[clean]
|
||||||
|
# (可选)清除命令
|
||||||
|
clean-command = "make distclean"
|
@ -47,3 +47,4 @@ clean-command = "make clean"
|
|||||||
|
|
||||||
# 环境变量
|
# 环境变量
|
||||||
# 注意:因为没有环境变量,所以这里不包含[[envs]]部分
|
# 注意:因为没有环境变量,所以这里不包含[[envs]]部分
|
||||||
|
|
||||||
|
4
user/sysconfig/etc/init.d/rcS
Executable file
4
user/sysconfig/etc/init.d/rcS
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
echo "[rcS] Running system init script..."
|
||||||
|
/bin/about.elf
|
||||||
|
/bin/busybox stty erase 127
|
27
user/sysconfig/etc/inittab
Normal file
27
user/sysconfig/etc/inittab
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# /etc/inittab
|
||||||
|
::sysinit:busybox sh /etc/init.d/rcS # 系统初始化脚本
|
||||||
|
|
||||||
|
::askfirst:-/bin/busybox sh --login
|
||||||
|
|
||||||
|
|
||||||
|
# /etc/inittab - 根据源码弄出来的默认inittab
|
||||||
|
# https://code.dragonos.org.cn/xref/busybox-1.35.0/init/init.c#679
|
||||||
|
|
||||||
|
# # 系统初始化脚本
|
||||||
|
# ::sysinit:/etc/init.d/rcS
|
||||||
|
|
||||||
|
# # askfirst shell
|
||||||
|
# ::askfirst:-/bin/sh
|
||||||
|
# tty2::askfirst:-/bin/sh
|
||||||
|
# tty3::askfirst:-/bin/sh
|
||||||
|
# tty4::askfirst:-/bin/sh
|
||||||
|
|
||||||
|
# # Ctrl-Alt-Del 重启
|
||||||
|
# ::ctrlaltdel:/sbin/reboot
|
||||||
|
|
||||||
|
# # 系统关闭或重启前的动作
|
||||||
|
# ::shutdown:/bin/umount -a -r
|
||||||
|
# ::shutdown:/sbin/swapoff -a
|
||||||
|
|
||||||
|
# # 收到 QUIT 信号时重启 init
|
||||||
|
# ::restart:/sbin/init
|
2
user/sysconfig/etc/profile
Normal file
2
user/sysconfig/etc/profile
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
export PATH=/bin:/usr/bin:/usr/local/bin
|
@ -6,3 +6,5 @@ Type=simple
|
|||||||
ExecStart=/bin/NovaShell
|
ExecStart=/bin/NovaShell
|
||||||
Restart=always
|
Restart=always
|
||||||
ExecStartPre=-/bin/about.elf
|
ExecStartPre=-/bin/about.elf
|
||||||
|
ExecStartPre=/bin/busybox stty erase 127
|
||||||
|
Environment=PATH=/bin:/usr/bin:/usr/local/bin
|
Loading…
x
Reference in New Issue
Block a user