refactor(process): 重构process下的系统调用 (#1184)

* refactor(process):迁移geteuid系统调用

* refactor(process):迁移getegid系统调用

* refactor(process):迁移getgid系统调用

* refactor(process):迁移getpgid系统调用

* refactor(process):迁移getpid系统调用

* refactor(process):迁移getppid系统调用

* refactor(process):迁移getsid系统调用

* refactor(process):迁移gettid系统调用

* refactor(process):迁移getuid系统调用

* refactor(process):迁移set_tid_address系统调用

* refactor(process):迁移setfsgid系统调用

* refactor(process):迁移setfsuid系统调用

* refactor(process):迁移setgid系统调用

* refactor(process):迁移setpgid系统调用

* refactor(process):迁移setresgid系统调用

* refactor(process):迁移setresuid系统调用

* refactor(process):迁移setsid系统调用

* refactor(process):迁移setuid系统调用

* refactor(process):删除部分已迁移的syscall(id相关)的原有部分

* refactor(process):make fmt

* refactor(process):迁移sys_get_rusage系统调用

* refactor(process):迁移exit exit_group 系统调用

* refactor(process):删除重构syscall下的mod中的全架构条件编译

* refactor(process):迁移sys_wait4系统调用

* refactor(process):迁移sys_getrlimit sys_prlimit64 系统调用

* make fmt

* refactor(process):迁移sys_uname系统调用

* fix(ipc):修复rebase时的错误冲突

* refactor(process):修改已迁移的系统调用的handle参数from_user-->frame

* refactor(process):迁移execve系统调用

* refactor(process):迁移clone系统调用

* refactor(process):迁移fork、vfork系统调用

* refactor(process):删除原有syscall文件,将迁移后的文件夹重命名为syscall

* refactor(process):修复条件编译错误
This commit is contained in:
DoL 2025-06-04 21:29:51 +08:00 committed by GitHub
parent 58e7943c13
commit 326cf3e0a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
38 changed files with 1654 additions and 830 deletions

View File

@ -13,11 +13,10 @@ use crate::{
namespaces::NsProxy,
net::net_core::net_init,
process::{
exec::ProcInitInfo, kthread::KernelThreadMechanism, stdio::stdio_init, ProcessFlags,
ProcessManager,
exec::ProcInitInfo, execve::do_execve, kthread::KernelThreadMechanism, stdio::stdio_init,
ProcessFlags, ProcessManager,
},
smp::smp_init,
syscall::Syscall,
};
use super::{cmdline::kenrel_cmdline_param_manager, initcall::do_initcalls};
@ -164,7 +163,7 @@ fn run_init_process(
ProcessManager::current_pcb().set_nsproxy(NsProxy::new()); // 初始化init进程的namespace
let path = proc_init_info.proc_name.to_str().unwrap();
Syscall::do_execve(
do_execve(
path.to_string(),
proc_init_info.args.clone(),
proc_init_info.envs.clone(),

View File

@ -25,8 +25,8 @@ use crate::libs::rbtree::RBTree;
use crate::libs::rwlock::RwLock;
use crate::libs::wait_queue::WaitQueue;
use crate::process::fork::CloneFlags;
use crate::process::geteuid::do_geteuid;
use crate::process::ProcessManager;
use crate::syscall::Syscall;
#[allow(dead_code)]
#[derive(Debug)]
pub struct MntNamespace {
@ -230,7 +230,7 @@ impl MntNamespace {
) -> Result<Option<Arc<UCounts>>, SystemError> {
Ok(self
.ucounts
.inc_ucounts(user_ns, Syscall::geteuid()?, MntNamespaces))
.inc_ucounts(user_ns, do_geteuid()?, MntNamespaces))
}
pub fn dec_mnt_namespace(&self, uc: Arc<UCounts>) {

View File

@ -9,8 +9,8 @@ use crate::container_of;
use crate::filesystem::vfs::{IndexNode, ROOT_INODE};
use crate::namespaces::namespace::NsOperations;
use crate::process::fork::CloneFlags;
use crate::process::geteuid::do_geteuid;
use crate::process::ProcessManager;
use crate::syscall::Syscall;
use crate::{libs::rwlock::RwLock, process::Pid};
use alloc::boxed::Box;
use alloc::string::String;
@ -264,7 +264,7 @@ impl PidNamespace {
) -> Result<Option<Arc<UCounts>>, SystemError> {
Ok(self
.ucounts
.inc_ucounts(user_ns, Syscall::geteuid()?, PidNamespaces))
.inc_ucounts(user_ns, do_geteuid()?, PidNamespaces))
}
pub fn dec_pid_namespaces(&mut self, uc: Arc<UCounts>) {

View File

@ -0,0 +1,113 @@
use crate::arch::CurrentIrqArch;
use crate::exception::InterruptArch;
use crate::process::exec::{load_binary_file, ExecParam, ExecParamFlags};
use crate::process::ProcessManager;
use crate::syscall::Syscall;
use crate::{libs::rand::rand_bytes, mm::ucontext::AddressSpace};
use crate::arch::interrupt::TrapFrame;
use alloc::{ffi::CString, string::String, sync::Arc, vec::Vec};
use system_error::SystemError;
pub fn do_execve(
path: String,
argv: Vec<CString>,
envp: Vec<CString>,
regs: &mut TrapFrame,
) -> Result<(), SystemError> {
let address_space = AddressSpace::new(true).expect("Failed to create new address space");
// debug!("to load binary file");
let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC)?;
let old_vm = do_execve_switch_user_vm(address_space.clone());
// 加载可执行文件
let load_result = load_binary_file(&mut param).inspect_err(|_| {
if let Some(old_vm) = old_vm {
do_execve_switch_user_vm(old_vm);
}
})?;
// debug!("load binary file done");
// debug!("argv: {:?}, envp: {:?}", argv, envp);
param.init_info_mut().args = argv;
param.init_info_mut().envs = envp;
// // 生成16字节随机数
param.init_info_mut().rand_num = rand_bytes::<16>();
// 把proc_init_info写到用户栈上
let mut ustack_message = unsafe {
address_space
.write()
.user_stack_mut()
.expect("No user stack found")
.clone_info_only()
};
let (user_sp, argv_ptr) = unsafe {
param
.init_info_mut()
.push_at(
// address_space
// .write()
// .user_stack_mut()
// .expect("No user stack found"),
&mut ustack_message,
)
.expect("Failed to push proc_init_info to user stack")
};
address_space.write().user_stack = Some(ustack_message);
Syscall::arch_do_execve(regs, &param, &load_result, user_sp, argv_ptr)
}
/// 切换用户虚拟内存空间
///
/// 该函数用于在执行系统调用 `execve` 时切换用户进程的虚拟内存空间。
///
/// # 参数
/// - `new_vm`: 新的用户地址空间,类型为 `Arc<AddressSpace>`。
///
/// # 返回值
/// - 返回旧的用户地址空间的引用,类型为 `Option<Arc<AddressSpace>>`。
///
/// # 错误处理
/// 如果地址空间切换失败,函数会触发断言失败,并输出错误信息。
fn do_execve_switch_user_vm(new_vm: Arc<AddressSpace>) -> Option<Arc<AddressSpace>> {
// 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
let pcb = ProcessManager::current_pcb();
// log::debug!(
// "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n",
// pcb.pid(),
// path,
// argv,
// envp
// );
let mut basic_info = pcb.basic_mut();
// 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它可能会造成内存use after free)
let old_address_space = basic_info.user_vm();
// 在pcb中原来的用户地址空间
unsafe {
basic_info.set_user_vm(None);
}
// 创建新的地址空间并设置为当前地址空间
unsafe {
basic_info.set_user_vm(Some(new_vm.clone()));
}
// to avoid deadlock
drop(basic_info);
assert!(
AddressSpace::is_current(&new_vm),
"Failed to set address space"
);
// debug!("Switch to new address space");
// 切换到新的用户地址空间
unsafe { new_vm.read().user_mapper.utable.make_current() };
drop(irq_guard);
old_address_space
}

View File

@ -0,0 +1,8 @@
use system_error::SystemError;
use crate::process::ProcessManager;
pub fn do_geteuid() -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
return Ok(pcb.cred.lock().euid.data());
}

View File

@ -76,8 +76,10 @@ use self::{cred::Cred, kthread::WorkerPrivate};
pub mod abi;
pub mod cred;
pub mod exec;
pub mod execve;
pub mod exit;
pub mod fork;
pub mod geteuid;
pub mod idle;
pub mod kthread;
pub mod pid;

View File

@ -1,683 +0,0 @@
use core::ffi::c_void;
use alloc::{
ffi::CString,
string::{String, ToString},
sync::Arc,
vec::Vec,
};
use log::error;
use system_error::SystemError;
use super::{
abi::WaitOption,
cred::{Kgid, Kuid},
exec::{load_binary_file, ExecParam, ExecParamFlags},
exit::kernel_wait4,
fork::{CloneFlags, KernelCloneArgs},
resource::{RLimit64, RLimitID, RUsage, RUsageWho},
KernelStack, Pgid, Pid, ProcessManager,
};
use crate::{
arch::{interrupt::TrapFrame, CurrentIrqArch, MMArch},
exception::InterruptArch,
filesystem::{
procfs::procfs_register_pid,
vfs::{file::FileDescriptorVec, MAX_PATHLEN},
},
libs::rand::rand_bytes,
mm::{
ucontext::{AddressSpace, UserStack},
verify_area, MemoryManagementArch, VirtAddr,
},
process::ProcessControlBlock,
sched::completion::Completion,
syscall::{
user_access::{check_and_clone_cstr, check_and_clone_cstr_array, UserBufferWriter},
Syscall,
},
};
//参考资料https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/utsname.h#17
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct PosixOldUtsName {
pub sysname: [u8; 65],
pub nodename: [u8; 65],
pub release: [u8; 65],
pub version: [u8; 65],
pub machine: [u8; 65],
}
impl PosixOldUtsName {
pub fn new() -> Self {
const SYS_NAME: &[u8] = b"Linux";
const NODENAME: &[u8] = b"DragonOS";
const RELEASE: &[u8] = b"5.19.0";
const VERSION: &[u8] = b"5.19.0";
#[cfg(target_arch = "x86_64")]
const MACHINE: &[u8] = b"x86_64";
#[cfg(target_arch = "aarch64")]
const MACHINE: &[u8] = b"aarch64";
#[cfg(target_arch = "riscv64")]
const MACHINE: &[u8] = b"riscv64";
#[cfg(target_arch = "loongarch64")]
const MACHINE: &[u8] = b"longarch64";
let mut r = Self {
sysname: [0; 65],
nodename: [0; 65],
release: [0; 65],
version: [0; 65],
machine: [0; 65],
};
r.sysname[0..SYS_NAME.len()].copy_from_slice(SYS_NAME);
r.nodename[0..NODENAME.len()].copy_from_slice(NODENAME);
r.release[0..RELEASE.len()].copy_from_slice(RELEASE);
r.version[0..VERSION.len()].copy_from_slice(VERSION);
r.machine[0..MACHINE.len()].copy_from_slice(MACHINE);
return r;
}
}
impl Syscall {
pub fn fork(frame: &TrapFrame) -> Result<usize, SystemError> {
ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into())
}
pub fn vfork(frame: &TrapFrame) -> Result<usize, SystemError> {
// 由于Linux vfork需要保证子进程先运行除非子进程调用execve或者exit
// 而我们目前没有实现这个特性所以暂时使用fork代替vforklinux文档表示这样也是也可以的
Self::fork(frame)
// 下面是以前的实现,除非我们实现了子进程先运行的特性,否则不要使用,不然会导致父进程数据损坏
// ProcessManager::fork(
// frame,
// CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL,
// )
// .map(|pid| pid.into())
}
pub fn execve(
path: *const u8,
argv: *const *const u8,
envp: *const *const u8,
frame: &mut TrapFrame,
) -> Result<(), SystemError> {
// debug!(
// "execve path: {:?}, argv: {:?}, envp: {:?}\n",
// path,
// argv,
// envp
// );
// debug!(
// "before execve: strong count: {}",
// Arc::strong_count(&ProcessManager::current_pcb())
// );
if path.is_null() {
return Err(SystemError::EINVAL);
}
let x = || {
let path: CString = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let argv: Vec<CString> = check_and_clone_cstr_array(argv)?;
let envp: Vec<CString> = check_and_clone_cstr_array(envp)?;
Ok((path, argv, envp))
};
let (path, argv, envp) = x().inspect_err(|e: &SystemError| {
error!("Failed to execve: {:?}", e);
})?;
let path = path.into_string().map_err(|_| SystemError::EINVAL)?;
ProcessManager::current_pcb()
.basic_mut()
.set_name(ProcessControlBlock::generate_name(&path, &argv));
Self::do_execve(path.clone(), argv, envp, frame)?;
let pcb = ProcessManager::current_pcb();
// 关闭设置了O_CLOEXEC的文件描述符
let fd_table = pcb.fd_table();
fd_table.write().close_on_exec();
// debug!(
// "after execve: strong count: {}",
// Arc::strong_count(&ProcessManager::current_pcb())
// );
pcb.set_execute_path(path);
return Ok(());
}
pub fn do_execve(
path: String,
argv: Vec<CString>,
envp: Vec<CString>,
regs: &mut TrapFrame,
) -> Result<(), SystemError> {
let address_space = AddressSpace::new(true).expect("Failed to create new address space");
// debug!("to load binary file");
let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC)?;
let old_vm = do_execve_switch_user_vm(address_space.clone());
// 加载可执行文件
let load_result = load_binary_file(&mut param).inspect_err(|_| {
if let Some(old_vm) = old_vm {
do_execve_switch_user_vm(old_vm);
}
})?;
// debug!("load binary file done");
// debug!("argv: {:?}, envp: {:?}", argv, envp);
param.init_info_mut().args = argv;
param.init_info_mut().envs = envp;
// // 生成16字节随机数
param.init_info_mut().rand_num = rand_bytes::<16>();
// 把proc_init_info写到用户栈上
let mut ustack_message = unsafe {
address_space
.write()
.user_stack_mut()
.expect("No user stack found")
.clone_info_only()
};
let (user_sp, argv_ptr) = unsafe {
param
.init_info_mut()
.push_at(
// address_space
// .write()
// .user_stack_mut()
// .expect("No user stack found"),
&mut ustack_message,
)
.expect("Failed to push proc_init_info to user stack")
};
address_space.write().user_stack = Some(ustack_message);
Self::arch_do_execve(regs, &param, &load_result, user_sp, argv_ptr)
}
pub fn wait4(
pid: i32,
wstatus: *mut i32,
options: i32,
rusage: *mut c_void,
) -> Result<usize, SystemError> {
let options = WaitOption::from_bits(options as u32).ok_or(SystemError::EINVAL)?;
let wstatus_buf = if wstatus.is_null() {
None
} else {
Some(UserBufferWriter::new(
wstatus,
core::mem::size_of::<i32>(),
true,
)?)
};
let mut tmp_rusage = if rusage.is_null() {
None
} else {
Some(RUsage::default())
};
let r = kernel_wait4(pid, wstatus_buf, options, tmp_rusage.as_mut())?;
if !rusage.is_null() {
let mut rusage_buf = UserBufferWriter::new::<RUsage>(
rusage as *mut RUsage,
core::mem::size_of::<RUsage>(),
true,
)?;
rusage_buf.copy_one_to_user(&tmp_rusage.unwrap(), 0)?;
}
return Ok(r);
}
/// # 退出进程
///
/// ## 参数
///
/// - status: 退出状态
pub fn exit(status: usize) -> ! {
ProcessManager::exit((status & 0xff) << 8);
}
/// @brief 获取当前进程的pid
pub fn getpid() -> Result<Pid, SystemError> {
let current_pcb = ProcessManager::current_pcb();
// if let Some(pid_ns) = &current_pcb.get_nsproxy().read().pid_namespace {
// // 获取该进程在命名空间中的 PID
// return Ok(current_pcb.pid_strcut().read().numbers[pid_ns.level].nr);
// // 返回命名空间中的 PID
// }
// 默认返回 tgid
Ok(current_pcb.tgid())
}
/// @brief 获取指定进程的pgid
///
/// @param pid 指定一个进程号
///
/// @return 成功指定进程的进程组id
/// @return 错误,不存在该进程
pub fn getpgid(pid: Pid) -> Result<Pgid, SystemError> {
if pid == Pid(0) {
let current_pcb = ProcessManager::current_pcb();
return Ok(current_pcb.pgid());
}
let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
return Ok(target_proc.pgid());
}
/// 设置指定进程的pgid
///
/// ## 参数
///
/// - pid: 指定进程号
/// - pgid: 新的进程组号
///
/// ## 返回值
/// 无
pub fn setpgid(pid: Pid, pgid: Pgid) -> Result<usize, SystemError> {
let current_pcb = ProcessManager::current_pcb();
let pid = if pid == Pid(0) {
current_pcb.pid()
} else {
pid
};
let pgid = if pgid == Pgid::from(0) {
Pgid::from(pid.into())
} else {
pgid
};
if pid != current_pcb.pid() && !current_pcb.contain_child(&pid) {
return Err(SystemError::ESRCH);
}
if pgid.into() != pid.into() && ProcessManager::find_process_group(pgid).is_none() {
return Err(SystemError::EPERM);
}
let pcb = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
pcb.join_other_group(pgid)?;
return Ok(0);
}
/// 创建新的会话
pub fn setsid() -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
let session = pcb.go_to_new_session()?;
let mut guard = pcb.sig_info_mut();
guard.set_tty(None);
Ok(session.sid().into())
}
/// 获取指定进程的会话id
///
/// 若pid为0则返回当前进程的会话id
///
/// 若pid不为0则返回指定进程的会话id
pub fn getsid(pid: Pid) -> Result<usize, SystemError> {
let session = ProcessManager::current_pcb().session().unwrap();
let sid = session.sid().into();
if pid == Pid(0) {
return Ok(sid);
}
let pcb = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
if !Arc::ptr_eq(&session, &pcb.session().unwrap()) {
return Err(SystemError::EPERM);
}
return Ok(sid);
}
/// @brief 获取当前进程的父进程id
///
/// 若为initproc则ppid设置为0
pub fn getppid() -> Result<Pid, SystemError> {
let current_pcb = ProcessManager::current_pcb();
return Ok(current_pcb.basic().ppid());
}
pub fn clone(
current_trapframe: &TrapFrame,
clone_args: KernelCloneArgs,
) -> Result<usize, SystemError> {
let flags = clone_args.flags;
let vfork = Arc::new(Completion::new());
if flags.contains(CloneFlags::CLONE_PIDFD)
&& flags.contains(CloneFlags::CLONE_PARENT_SETTID)
{
return Err(SystemError::EINVAL);
}
let current_pcb = ProcessManager::current_pcb();
let new_kstack = KernelStack::new()?;
let name = current_pcb.basic().name().to_string();
let pcb = ProcessControlBlock::new(name, new_kstack);
// 克隆pcb
ProcessManager::copy_process(&current_pcb, &pcb, clone_args, current_trapframe)?;
// 向procfs注册进程
procfs_register_pid(pcb.pid()).unwrap_or_else(|e| {
panic!(
"fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}",
pcb.pid(),
e
)
});
if flags.contains(CloneFlags::CLONE_VFORK) {
pcb.thread.write_irqsave().vfork_done = Some(vfork.clone());
}
if pcb.thread.read_irqsave().set_child_tid.is_some() {
let addr = pcb.thread.read_irqsave().set_child_tid.unwrap();
let mut writer =
UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?;
}
ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
panic!(
"fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}",
pcb.pid(),
e
)
});
if flags.contains(CloneFlags::CLONE_VFORK) {
// 等待子进程结束或者exec;
vfork.wait_for_completion_interruptible()?;
}
return Ok(pcb.pid().0);
}
/// 设置线程地址
pub fn set_tid_address(ptr: usize) -> Result<usize, SystemError> {
verify_area(VirtAddr::new(ptr), core::mem::size_of::<i32>())
.map_err(|_| SystemError::EFAULT)?;
let pcb = ProcessManager::current_pcb();
pcb.thread.write_irqsave().clear_child_tid = Some(VirtAddr::new(ptr));
Ok(pcb.pid.0)
}
pub fn gettid() -> Result<Pid, SystemError> {
let pcb = ProcessManager::current_pcb();
Ok(pcb.pid)
}
pub fn getuid() -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
return Ok(pcb.cred.lock().uid.data());
}
pub fn getgid() -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
return Ok(pcb.cred.lock().gid.data());
}
pub fn geteuid() -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
return Ok(pcb.cred.lock().euid.data());
}
pub fn getegid() -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
return Ok(pcb.cred.lock().egid.data());
}
pub fn setuid(uid: usize) -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
let mut guard = pcb.cred.lock();
if guard.uid.data() == 0 {
guard.setuid(uid);
guard.seteuid(uid);
guard.setsuid(uid);
} else if uid == guard.uid.data() || uid == guard.suid.data() {
guard.seteuid(uid);
} else {
return Err(SystemError::EPERM);
}
return Ok(0);
}
pub fn setgid(gid: usize) -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
let mut guard = pcb.cred.lock();
if guard.egid.data() == 0 {
guard.setgid(gid);
guard.setegid(gid);
guard.setsgid(gid);
guard.setfsgid(gid);
} else if guard.gid.data() == gid || guard.sgid.data() == gid {
guard.setegid(gid);
guard.setfsgid(gid);
} else {
return Err(SystemError::EPERM);
}
return Ok(0);
}
pub fn seteuid(euid: usize) -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
let mut guard = pcb.cred.lock();
if euid == usize::MAX || (euid == guard.euid.data() && euid == guard.fsuid.data()) {
return Ok(0);
}
if euid != usize::MAX {
guard.seteuid(euid);
}
let euid = guard.euid.data();
guard.setfsuid(euid);
return Ok(0);
}
pub fn setegid(egid: usize) -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
let mut guard = pcb.cred.lock();
if egid == usize::MAX || (egid == guard.egid.data() && egid == guard.fsgid.data()) {
return Ok(0);
}
if egid != usize::MAX {
guard.setegid(egid);
}
let egid = guard.egid.data();
guard.setfsgid(egid);
return Ok(0);
}
pub fn setfsuid(fsuid: usize) -> Result<usize, SystemError> {
let fsuid = Kuid::new(fsuid);
let pcb = ProcessManager::current_pcb();
let mut guard = pcb.cred.lock();
let old_fsuid = guard.fsuid;
if fsuid == guard.uid || fsuid == guard.euid || fsuid == guard.suid {
guard.setfsuid(fsuid.data());
}
Ok(old_fsuid.data())
}
pub fn setfsgid(fsgid: usize) -> Result<usize, SystemError> {
let fsgid = Kgid::new(fsgid);
let pcb = ProcessManager::current_pcb();
let mut guard = pcb.cred.lock();
let old_fsgid = guard.fsgid;
if fsgid == guard.gid || fsgid == guard.egid || fsgid == guard.sgid {
guard.setfsgid(fsgid.data());
}
Ok(old_fsgid.data())
}
pub fn get_rusage(who: i32, rusage: *mut RUsage) -> Result<usize, SystemError> {
let who = RUsageWho::try_from(who)?;
let mut writer = UserBufferWriter::new(rusage, core::mem::size_of::<RUsage>(), true)?;
let pcb = ProcessManager::current_pcb();
let rusage = pcb.get_rusage(who).ok_or(SystemError::EINVAL)?;
let ubuf = writer.buffer::<RUsage>(0).unwrap();
ubuf.copy_from_slice(&[rusage]);
return Ok(0);
}
/// # 设置资源限制
///
/// TODO: 目前暂时不支持设置资源限制,只提供读取默认值的功能
///
/// ## 参数
///
/// - pid: 进程号
/// - resource: 资源类型
/// - new_limit: 新的资源限制
/// - old_limit: 旧的资源限制
///
/// ## 返回值
///
/// - 成功0
/// - 如果old_limit不为NULL则返回旧的资源限制到old_limit
///
pub fn prlimit64(
_pid: Pid,
resource: usize,
_new_limit: *const RLimit64,
old_limit: *mut RLimit64,
) -> Result<usize, SystemError> {
let resource = RLimitID::try_from(resource)?;
let mut writer = None;
if !old_limit.is_null() {
writer = Some(UserBufferWriter::new(
old_limit,
core::mem::size_of::<RLimit64>(),
true,
)?);
}
match resource {
RLimitID::Stack => {
if let Some(mut writer) = writer {
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
rlimit.rlim_cur = UserStack::DEFAULT_USER_STACK_SIZE as u64;
rlimit.rlim_max = UserStack::DEFAULT_USER_STACK_SIZE as u64;
}
return Ok(0);
}
RLimitID::Nofile => {
if let Some(mut writer) = writer {
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
rlimit.rlim_cur = FileDescriptorVec::PROCESS_MAX_FD as u64;
rlimit.rlim_max = FileDescriptorVec::PROCESS_MAX_FD as u64;
}
return Ok(0);
}
RLimitID::As | RLimitID::Rss => {
if let Some(mut writer) = writer {
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
rlimit.rlim_cur = MMArch::USER_END_VADDR.data() as u64;
rlimit.rlim_max = MMArch::USER_END_VADDR.data() as u64;
}
return Ok(0);
}
_ => {
return Err(SystemError::ENOSYS);
}
}
}
pub fn uname(name: *mut PosixOldUtsName) -> Result<usize, SystemError> {
let mut writer =
UserBufferWriter::new(name, core::mem::size_of::<PosixOldUtsName>(), true)?;
writer.copy_one_to_user(&PosixOldUtsName::new(), 0)?;
return Ok(0);
}
}
/// 切换用户虚拟内存空间
///
/// 该函数用于在执行系统调用 `execve` 时切换用户进程的虚拟内存空间。
///
/// # 参数
/// - `new_vm`: 新的用户地址空间,类型为 `Arc<AddressSpace>`。
///
/// # 返回值
/// - 返回旧的用户地址空间的引用,类型为 `Option<Arc<AddressSpace>>`。
///
/// # 错误处理
/// 如果地址空间切换失败,函数会触发断言失败,并输出错误信息。
fn do_execve_switch_user_vm(new_vm: Arc<AddressSpace>) -> Option<Arc<AddressSpace>> {
// 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
let pcb = ProcessManager::current_pcb();
// log::debug!(
// "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n",
// pcb.pid(),
// path,
// argv,
// envp
// );
let mut basic_info = pcb.basic_mut();
// 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它可能会造成内存use after free)
let old_address_space = basic_info.user_vm();
// 在pcb中原来的用户地址空间
unsafe {
basic_info.set_user_vm(None);
}
// 创建新的地址空间并设置为当前地址空间
unsafe {
basic_info.set_user_vm(Some(new_vm.clone()));
}
// to avoid deadlock
drop(basic_info);
assert!(
AddressSpace::is_current(&new_vm),
"Failed to set address space"
);
// debug!("Switch to new address space");
// 切换到新的用户地址空间
unsafe { new_vm.read().user_mapper.utable.make_current() };
drop(irq_guard);
old_address_space
}

View File

@ -0,0 +1,81 @@
mod sys_clone;
mod sys_execve;
mod sys_exit;
mod sys_exit_group;
mod sys_get_rusage;
mod sys_getegid;
mod sys_geteuid;
mod sys_getgid;
mod sys_getpgid;
mod sys_getpid;
mod sys_getppid;
mod sys_getsid;
mod sys_gettid;
mod sys_getuid;
mod sys_prlimit64;
mod sys_set_tid_address;
mod sys_setfsgid;
mod sys_setfsuid;
mod sys_setgid;
mod sys_setpgid;
mod sys_setresgid;
mod sys_setresuid;
mod sys_setsid;
mod sys_setuid;
mod sys_uname;
mod sys_wait4;
#[cfg(target_arch = "x86_64")]
mod sys_fork;
#[cfg(target_arch = "x86_64")]
mod sys_getrlimit;
#[cfg(target_arch = "x86_64")]
mod sys_vfork;
//参考资料https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/utsname.h#17
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct PosixOldUtsName {
pub sysname: [u8; 65],
pub nodename: [u8; 65],
pub release: [u8; 65],
pub version: [u8; 65],
pub machine: [u8; 65],
}
impl PosixOldUtsName {
pub fn new() -> Self {
const SYS_NAME: &[u8] = b"Linux";
const NODENAME: &[u8] = b"DragonOS";
const RELEASE: &[u8] = b"5.19.0";
const VERSION: &[u8] = b"5.19.0";
#[cfg(target_arch = "x86_64")]
const MACHINE: &[u8] = b"x86_64";
#[cfg(target_arch = "aarch64")]
const MACHINE: &[u8] = b"aarch64";
#[cfg(target_arch = "riscv64")]
const MACHINE: &[u8] = b"riscv64";
#[cfg(target_arch = "loongarch64")]
const MACHINE: &[u8] = b"longarch64";
let mut r = Self {
sysname: [0; 65],
nodename: [0; 65],
release: [0; 65],
version: [0; 65],
machine: [0; 65],
};
r.sysname[0..SYS_NAME.len()].copy_from_slice(SYS_NAME);
r.nodename[0..NODENAME.len()].copy_from_slice(NODENAME);
r.release[0..RELEASE.len()].copy_from_slice(RELEASE);
r.version[0..VERSION.len()].copy_from_slice(VERSION);
r.machine[0..MACHINE.len()].copy_from_slice(MACHINE);
return r;
}
}

View File

@ -0,0 +1,128 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_CLONE;
use crate::filesystem::procfs::procfs_register_pid;
use crate::mm::{verify_area, VirtAddr};
use crate::process::fork::{CloneFlags, KernelCloneArgs};
use crate::process::{KernelStack, ProcessControlBlock, ProcessManager};
use crate::sched::completion::Completion;
use crate::syscall::table::{FormattedSyscallParam, Syscall};
use crate::syscall::user_access::UserBufferWriter;
use alloc::vec::Vec;
use alloc::{string::ToString, sync::Arc};
use system_error::SystemError;
pub struct SysClone;
impl SysClone {
fn parent_tid(args: &[usize]) -> VirtAddr {
VirtAddr::new(args[2])
}
fn child_tid(args: &[usize]) -> VirtAddr {
VirtAddr::new(args[3])
}
fn flags(args: &[usize]) -> CloneFlags {
CloneFlags::from_bits_truncate(args[0] as u64)
}
fn stack(args: &[usize]) -> usize {
args[1]
}
fn tls(args: &[usize]) -> usize {
args[4]
}
}
impl Syscall for SysClone {
fn num_args(&self) -> usize {
5
}
fn handle(&self, args: &[usize], frame: &mut TrapFrame) -> Result<usize, SystemError> {
let parent_tid = Self::parent_tid(args);
let child_tid = Self::child_tid(args);
// 地址校验
verify_area(parent_tid, core::mem::size_of::<i32>())?;
verify_area(child_tid, core::mem::size_of::<i32>())?;
let flags = Self::flags(args);
let stack = Self::stack(args);
let tls = Self::tls(args);
let mut clone_args = KernelCloneArgs::new();
clone_args.flags = flags;
clone_args.stack = stack;
clone_args.parent_tid = parent_tid;
clone_args.child_tid = child_tid;
clone_args.tls = tls;
let vfork = Arc::new(Completion::new());
if flags.contains(CloneFlags::CLONE_PIDFD)
&& flags.contains(CloneFlags::CLONE_PARENT_SETTID)
{
return Err(SystemError::EINVAL);
}
let current_pcb = ProcessManager::current_pcb();
let new_kstack = KernelStack::new()?;
let name = current_pcb.basic().name().to_string();
let pcb = ProcessControlBlock::new(name, new_kstack);
// 克隆pcb
ProcessManager::copy_process(&current_pcb, &pcb, clone_args, frame)?;
// 向procfs注册进程
procfs_register_pid(pcb.pid()).unwrap_or_else(|e| {
panic!(
"fork: Failed to register pid to procfs, pid: [{:?}]. Error: {:?}",
pcb.pid(),
e
)
});
if flags.contains(CloneFlags::CLONE_VFORK) {
pcb.thread.write_irqsave().vfork_done = Some(vfork.clone());
}
if pcb.thread.read_irqsave().set_child_tid.is_some() {
let addr = pcb.thread.read_irqsave().set_child_tid.unwrap();
let mut writer =
UserBufferWriter::new(addr.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
writer.copy_one_to_user(&(pcb.pid().data() as i32), 0)?;
}
ProcessManager::wakeup(&pcb).unwrap_or_else(|e| {
panic!(
"fork: Failed to wakeup new process, pid: [{:?}]. Error: {:?}",
pcb.pid(),
e
)
});
if flags.contains(CloneFlags::CLONE_VFORK) {
// 等待子进程结束或者exec;
vfork.wait_for_completion_interruptible()?;
}
return Ok(pcb.pid().0);
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![
FormattedSyscallParam::new(
"parent_tid",
format!("{:#x}", Self::parent_tid(args).data()),
),
FormattedSyscallParam::new("child_tid", format!("{:#x}", Self::child_tid(args).data())),
FormattedSyscallParam::new("flags", format!("{:#x}", Self::flags(args))),
FormattedSyscallParam::new("stack", format!("{:#x}", Self::stack(args))),
FormattedSyscallParam::new("tls", format!("{:#x}", Self::tls(args))),
]
}
}
syscall_table_macros::declare_syscall!(SYS_CLONE, SysClone);

View File

@ -0,0 +1,98 @@
use log::error;
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_EXECVE;
use crate::filesystem::vfs::MAX_PATHLEN;
use crate::mm::page::PAGE_4K_SIZE;
use crate::mm::{verify_area, VirtAddr};
use crate::process::execve::do_execve;
use crate::process::{ProcessControlBlock, ProcessManager};
use crate::syscall::table::{FormattedSyscallParam, Syscall};
use crate::syscall::user_access::{check_and_clone_cstr, check_and_clone_cstr_array};
use alloc::{ffi::CString, vec::Vec};
use system_error::SystemError;
pub struct SysExecve;
impl SysExecve {
fn path_ptr(args: &[usize]) -> usize {
args[0]
}
fn argv_ptr(args: &[usize]) -> usize {
args[1]
}
fn env_ptr(args: &[usize]) -> usize {
args[2]
}
}
impl Syscall for SysExecve {
fn num_args(&self) -> usize {
3
}
fn handle(&self, args: &[usize], frame: &mut TrapFrame) -> Result<usize, SystemError> {
let path_ptr = Self::path_ptr(args);
let argv_ptr = Self::argv_ptr(args);
let env_ptr = Self::env_ptr(args);
let virt_path_ptr = VirtAddr::new(path_ptr);
let virt_argv_ptr = VirtAddr::new(argv_ptr);
let virt_env_ptr = VirtAddr::new(env_ptr);
// 权限校验
if frame.is_from_user()
&& (verify_area(virt_path_ptr, MAX_PATHLEN).is_err()
|| verify_area(virt_argv_ptr, PAGE_4K_SIZE).is_err())
|| verify_area(virt_env_ptr, PAGE_4K_SIZE).is_err()
{
Err(SystemError::EFAULT)
} else {
let path = path_ptr as *const u8;
let argv = argv_ptr as *const *const u8;
let envp = env_ptr as *const *const u8;
if path.is_null() {
return Err(SystemError::EINVAL);
}
let x = || {
let path: CString = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
let argv: Vec<CString> = check_and_clone_cstr_array(argv)?;
let envp: Vec<CString> = check_and_clone_cstr_array(envp)?;
Ok((path, argv, envp))
};
let (path, argv, envp) = x().inspect_err(|e: &SystemError| {
error!("Failed to execve: {:?}", e);
})?;
let path = path.into_string().map_err(|_| SystemError::EINVAL)?;
ProcessManager::current_pcb()
.basic_mut()
.set_name(ProcessControlBlock::generate_name(&path, &argv));
do_execve(path.clone(), argv, envp, frame)?;
let pcb = ProcessManager::current_pcb();
// 关闭设置了O_CLOEXEC的文件描述符
let fd_table = pcb.fd_table();
fd_table.write().close_on_exec();
pcb.set_execute_path(path);
return Ok(0);
}
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![
FormattedSyscallParam::new("path", format!("{:#x}", Self::path_ptr(args))),
FormattedSyscallParam::new("argv", format!("{:#x}", Self::argv_ptr(args))),
FormattedSyscallParam::new("env", format!("{:#x}", Self::env_ptr(args))),
]
}
}
syscall_table_macros::declare_syscall!(SYS_EXECVE, SysExecve);

View File

@ -0,0 +1,34 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_EXIT;
use crate::process::ProcessManager;
use crate::syscall::table::{FormattedSyscallParam, Syscall};
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysExit;
impl SysExit {
fn exit_code(args: &[usize]) -> usize {
args[0]
}
}
impl Syscall for SysExit {
fn num_args(&self) -> usize {
1
}
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let exit_code = Self::exit_code(args);
ProcessManager::exit((exit_code & 0xff) << 8);
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"exit_code",
format!("{:#x}", Self::exit_code(args)),
)]
}
}
syscall_table_macros::declare_syscall!(SYS_EXIT, SysExit);

View File

@ -0,0 +1,34 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_EXIT_GROUP;
use crate::process::ProcessManager;
use crate::syscall::table::{FormattedSyscallParam, Syscall};
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysExitGroup;
impl SysExitGroup {
fn exit_code(args: &[usize]) -> usize {
args[0]
}
}
impl Syscall for SysExitGroup {
fn num_args(&self) -> usize {
1
}
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let exit_code = Self::exit_code(args);
ProcessManager::exit((exit_code & 0xff) << 8);
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"exit_code",
format!("{:#x}", Self::exit_code(args)),
)]
}
}
syscall_table_macros::declare_syscall!(SYS_EXIT_GROUP, SysExitGroup);

View File

@ -0,0 +1,26 @@
use crate::arch::interrupt::TrapFrame;
//use crate::arch::syscall::nr::SYS_FORK;
use crate::process::fork::CloneFlags;
use crate::process::ProcessManager;
use crate::syscall::table::{FormattedSyscallParam, Syscall};
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysFork;
impl Syscall for SysFork {
fn num_args(&self) -> usize {
0
}
fn handle(&self, _args: &[usize], frame: &mut TrapFrame) -> Result<usize, SystemError> {
log::debug!("fork");
ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into())
}
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![]
}
}
//syscall_table_macros::declare_syscall!(SYS_FORK, SysFork);

View File

@ -0,0 +1,52 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_GETRUSAGE;
use crate::process::resource::RUsageWho;
use crate::process::{resource::RUsage, ProcessManager};
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use crate::syscall::user_access::UserBufferWriter;
use alloc::vec::Vec;
use core::ffi::c_int;
use system_error::SystemError;
pub struct SysGetRusage;
impl SysGetRusage {
fn who(args: &[usize]) -> c_int {
args[0] as c_int
}
fn rusage(args: &[usize]) -> *mut RUsage {
args[1] as *mut RUsage
}
}
impl Syscall for SysGetRusage {
fn num_args(&self) -> usize {
2
}
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let who = Self::who(args);
let rusage = Self::rusage(args);
let who = RUsageWho::try_from(who)?;
let mut writer = UserBufferWriter::new(rusage, core::mem::size_of::<RUsage>(), true)?;
let pcb = ProcessManager::current_pcb();
let rusage = pcb.get_rusage(who).ok_or(SystemError::EINVAL)?;
let ubuf = writer.buffer::<RUsage>(0).unwrap();
ubuf.copy_from_slice(&[rusage]);
return Ok(0);
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![
FormattedSyscallParam::new("who", format!("{:#x}", Self::who(args))),
FormattedSyscallParam::new("rusage", format!("{:#x}", Self::rusage(args) as usize)),
]
}
}
syscall_table_macros::declare_syscall!(SYS_GETRUSAGE, SysGetRusage);

View File

@ -0,0 +1,26 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_GETEGID;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysGetEgid;
impl Syscall for SysGetEgid {
fn num_args(&self) -> usize {
0
}
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
return Ok(pcb.cred.lock().egid.data());
}
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![]
}
}
syscall_table_macros::declare_syscall!(SYS_GETEGID, SysGetEgid);

View File

@ -0,0 +1,25 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_GETEUID;
use crate::process::geteuid::do_geteuid;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysGetEuid;
impl Syscall for SysGetEuid {
fn num_args(&self) -> usize {
0
}
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
do_geteuid()
}
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![]
}
}
syscall_table_macros::declare_syscall!(SYS_GETEUID, SysGetEuid);

View File

@ -0,0 +1,25 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_GETGID;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysGetGid;
impl Syscall for SysGetGid {
fn num_args(&self) -> usize {
0
}
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
return Ok(pcb.cred.lock().gid.data());
}
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![]
}
}
syscall_table_macros::declare_syscall!(SYS_GETGID, SysGetGid);

View File

@ -0,0 +1,49 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_GETPGID;
use crate::process::Pid;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysGetPgid;
impl SysGetPgid {
fn pid(args: &[usize]) -> Pid {
Pid::new(args[0])
}
}
impl Syscall for SysGetPgid {
fn num_args(&self) -> usize {
1
}
/// # 函数的功能
/// 获取指定进程的pgid
///
/// ## 参数
/// - pid: 指定一个进程号
///
/// ## 返回值
/// - 成功指定进程的进程组id
/// - 错误,不存在该进程
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let pid = Self::pid(args);
if pid == Pid(0) {
let current_pcb = ProcessManager::current_pcb();
return Ok(current_pcb.pgid().into());
}
let target_proc = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
return Ok(target_proc.pgid().into());
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"pid",
format!("{:#x}", Self::pid(args).0),
)]
}
}
syscall_table_macros::declare_syscall!(SYS_GETPGID, SysGetPgid);

View File

@ -0,0 +1,33 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_GETPID;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysGetPid;
impl Syscall for SysGetPid {
fn num_args(&self) -> usize {
0
}
/// # 函数的功能
/// 获取当前进程的pid
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let current_pcb = ProcessManager::current_pcb();
// if let Some(pid_ns) = &current_pcb.get_nsproxy().read().pid_namespace {
// // 获取该进程在命名空间中的 PID
// return Ok(current_pcb.pid_strcut().read().numbers[pid_ns.level].nr);
// // 返回命名空间中的 PID
// }
// 默认返回 tgid
return Ok(current_pcb.tgid().into());
}
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![]
}
}
syscall_table_macros::declare_syscall!(SYS_GETPID, SysGetPid);

View File

@ -0,0 +1,27 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_GETPPID;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysGetPpid;
impl Syscall for SysGetPpid {
fn num_args(&self) -> usize {
0
}
/// # 函数的功能
/// 获取当前进程的父进程id
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let current_pcb = ProcessManager::current_pcb();
return Ok(current_pcb.basic().ppid().into());
}
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![]
}
}
syscall_table_macros::declare_syscall!(SYS_GETPPID, SysGetPpid);

View File

@ -0,0 +1,50 @@
use system_error::SystemError;
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_GETRLIMIT;
use crate::process::resource::RLimit64;
use crate::process::syscall::sys_prlimit64::do_prlimit64;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
pub struct SysGetRlimit;
impl SysGetRlimit {
fn resource(args: &[usize]) -> usize {
args[0]
}
fn rlimit(args: &[usize]) -> *mut RLimit64 {
args[1] as *mut RLimit64
}
}
impl Syscall for SysGetRlimit {
fn num_args(&self) -> usize {
2
}
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let resource = Self::resource(args);
let rlimit = Self::rlimit(args);
do_prlimit64(
ProcessManager::current_pcb().pid(),
resource,
core::ptr::null::<RLimit64>(),
rlimit,
)
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![
FormattedSyscallParam::new("resource", format!("{:#x}", Self::resource(args))),
FormattedSyscallParam::new("rlimit", format!("{:#x}", Self::rlimit(args) as usize)),
]
}
}
syscall_table_macros::declare_syscall!(SYS_GETRLIMIT, SysGetRlimit);

View File

@ -0,0 +1,54 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_GETSID;
use crate::process::Pid;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::sync::Arc;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysGetsid;
impl SysGetsid {
fn pid(args: &[usize]) -> Pid {
Pid::new(args[0])
}
}
impl Syscall for SysGetsid {
fn num_args(&self) -> usize {
1
}
/// # 函数的功能
/// 获取指定进程的会话id
///
/// 若pid为0则返回当前进程的会话id
///
/// 若pid不为0则返回指定进程的会话id
///
/// ## 参数
/// - pid: 指定一个进程号
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let pid = Self::pid(args);
let session = ProcessManager::current_pcb().session().unwrap();
let sid = session.sid().into();
if pid == Pid(0) {
return Ok(sid);
}
let pcb = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
if !Arc::ptr_eq(&session, &pcb.session().unwrap()) {
return Err(SystemError::EPERM);
}
return Ok(sid);
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"pid",
format!("{:#x}", Self::pid(args).0),
)]
}
}
syscall_table_macros::declare_syscall!(SYS_GETSID, SysGetsid);

View File

@ -0,0 +1,25 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_GETTID;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysGetTid;
impl Syscall for SysGetTid {
fn num_args(&self) -> usize {
0
}
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
return Ok(pcb.pid.into());
}
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![]
}
}
syscall_table_macros::declare_syscall!(SYS_GETTID, SysGetTid);

View File

@ -0,0 +1,26 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_GETUID;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysGetUid;
impl Syscall for SysGetUid {
fn num_args(&self) -> usize {
0
}
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
return Ok(pcb.cred.lock().uid.data());
}
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![]
}
}
syscall_table_macros::declare_syscall!(SYS_GETUID, SysGetUid);

View File

@ -0,0 +1,135 @@
use crate::arch::syscall::nr::SYS_PRLIMIT64;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use crate::{
arch::MMArch,
filesystem::vfs::file::FileDescriptorVec,
mm::{ucontext::UserStack, MemoryManagementArch},
process::{
resource::{RLimit64, RLimitID},
Pid,
},
syscall::user_access::UserBufferWriter,
};
use alloc::vec::Vec;
use system_error::SystemError;
use crate::arch::interrupt::TrapFrame;
pub struct SysPrlimit64;
impl SysPrlimit64 {
fn pid(args: &[usize]) -> Pid {
Pid::new(args[0])
}
fn resource(args: &[usize]) -> usize {
args[1]
}
fn new_limit(args: &[usize]) -> *const RLimit64 {
args[2] as *const RLimit64
}
fn old_limit(args: &[usize]) -> *mut RLimit64 {
args[3] as *mut RLimit64
}
}
impl Syscall for SysPrlimit64 {
fn num_args(&self) -> usize {
4
}
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let pid = Self::pid(args);
let resource = Self::resource(args);
let new_limit = Self::new_limit(args);
let old_limit = Self::old_limit(args);
do_prlimit64(pid, resource, new_limit, old_limit)
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![
FormattedSyscallParam::new("pid", format!("{:#x}", Self::pid(args).data())),
FormattedSyscallParam::new("resource", format!("{:#x}", Self::resource(args))),
FormattedSyscallParam::new(
"new_limit",
format!("{:#x}", Self::new_limit(args) as usize),
),
FormattedSyscallParam::new(
"old_limit",
format!("{:#x}", Self::old_limit(args) as usize),
),
]
}
}
syscall_table_macros::declare_syscall!(SYS_PRLIMIT64, SysPrlimit64);
/// # 设置资源限制
///
/// TODO: 目前暂时不支持设置资源限制,只提供读取默认值的功能
///
/// ## 参数
///
/// - pid: 进程号
/// - resource: 资源类型
/// - new_limit: 新的资源限制
/// - old_limit: 旧的资源限制
///
/// ## 返回值
///
/// - 成功0
/// - 如果old_limit不为NULL则返回旧的资源限制到old_limit
///
pub(super) fn do_prlimit64(
_pid: Pid,
resource: usize,
_new_limit: *const RLimit64,
old_limit: *mut RLimit64,
) -> Result<usize, SystemError> {
let resource = RLimitID::try_from(resource)?;
let mut writer = None;
if !old_limit.is_null() {
writer = Some(UserBufferWriter::new(
old_limit,
core::mem::size_of::<RLimit64>(),
true,
)?);
}
match resource {
RLimitID::Stack => {
if let Some(mut writer) = writer {
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
rlimit.rlim_cur = UserStack::DEFAULT_USER_STACK_SIZE as u64;
rlimit.rlim_max = UserStack::DEFAULT_USER_STACK_SIZE as u64;
}
return Ok(0);
}
RLimitID::Nofile => {
if let Some(mut writer) = writer {
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
rlimit.rlim_cur = FileDescriptorVec::PROCESS_MAX_FD as u64;
rlimit.rlim_max = FileDescriptorVec::PROCESS_MAX_FD as u64;
}
return Ok(0);
}
RLimitID::As | RLimitID::Rss => {
if let Some(mut writer) = writer {
let mut rlimit = writer.buffer::<RLimit64>(0).unwrap()[0];
rlimit.rlim_cur = MMArch::USER_END_VADDR.data() as u64;
rlimit.rlim_max = MMArch::USER_END_VADDR.data() as u64;
}
return Ok(0);
}
_ => {
return Err(SystemError::ENOSYS);
}
}
}

View File

@ -0,0 +1,43 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_SET_TID_ADDRESS;
use crate::mm::verify_area;
use crate::mm::VirtAddr;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysSetTidAddress;
impl SysSetTidAddress {
fn ptr(args: &[usize]) -> usize {
args[0]
}
}
impl Syscall for SysSetTidAddress {
fn num_args(&self) -> usize {
1
}
/// # 函数的功能
/// 设置线程地址
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let ptr = Self::ptr(args);
verify_area(VirtAddr::new(ptr), core::mem::size_of::<i32>())
.map_err(|_| SystemError::EFAULT)?;
let pcb = ProcessManager::current_pcb();
pcb.thread.write_irqsave().clear_child_tid = Some(VirtAddr::new(ptr));
Ok(pcb.pid.0)
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"ptr",
format!("{:#x}", Self::ptr(args)),
)]
}
}
syscall_table_macros::declare_syscall!(SYS_SET_TID_ADDRESS, SysSetTidAddress);

View File

@ -0,0 +1,46 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_SETFSGID;
use crate::process::cred::Kgid;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysSetFsgid;
impl SysSetFsgid {
fn fsgid(args: &[usize]) -> usize {
args[0]
}
}
impl Syscall for SysSetFsgid {
fn num_args(&self) -> usize {
1
}
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let fsgid = Self::fsgid(args);
let fsgid = Kgid::new(fsgid);
let pcb = ProcessManager::current_pcb();
let mut guard = pcb.cred.lock();
let old_fsgid = guard.fsgid;
if fsgid == guard.gid || fsgid == guard.egid || fsgid == guard.sgid {
guard.setfsgid(fsgid.data());
}
Ok(old_fsgid.data())
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"fsgid",
format!("{:#x}", Self::fsgid(args)),
)]
}
}
syscall_table_macros::declare_syscall!(SYS_SETFSGID, SysSetFsgid);

View File

@ -0,0 +1,45 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_SETFSUID;
use crate::process::cred::Kuid;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysSetFsuid;
impl SysSetFsuid {
fn fsuid(args: &[usize]) -> usize {
args[0]
}
}
impl Syscall for SysSetFsuid {
fn num_args(&self) -> usize {
1
}
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let fsuid = Self::fsuid(args);
let fsuid = Kuid::new(fsuid);
let pcb = ProcessManager::current_pcb();
let mut guard = pcb.cred.lock();
let old_fsuid = guard.fsuid;
if fsuid == guard.uid || fsuid == guard.euid || fsuid == guard.suid {
guard.setfsuid(fsuid.data());
}
Ok(old_fsuid.data())
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"fsuid",
format!("{:#x}", Self::fsuid(args)),
)]
}
}
syscall_table_macros::declare_syscall!(SYS_SETFSUID, SysSetFsuid);

View File

@ -0,0 +1,50 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_SETGID;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysSetGid;
impl SysSetGid {
fn gid(args: &[usize]) -> usize {
args[0]
}
}
impl Syscall for SysSetGid {
fn num_args(&self) -> usize {
1
}
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let gid = Self::gid(args);
let pcb = ProcessManager::current_pcb();
let mut guard = pcb.cred.lock();
if guard.egid.data() == 0 {
guard.setgid(gid);
guard.setegid(gid);
guard.setsgid(gid);
guard.setfsgid(gid);
} else if guard.gid.data() == gid || guard.sgid.data() == gid {
guard.setegid(gid);
guard.setfsgid(gid);
} else {
return Err(SystemError::EPERM);
}
return Ok(0);
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"gid",
format!("{:#x}", Self::gid(args)),
)]
}
}
syscall_table_macros::declare_syscall!(SYS_SETGID, SysSetGid);

View File

@ -0,0 +1,69 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_SETPGID;
use crate::process::Pgid;
use crate::process::Pid;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysSetPgid;
impl SysSetPgid {
fn pid(args: &[usize]) -> Pid {
Pid::new(args[0])
}
fn pgid(args: &[usize]) -> Pgid {
Pgid::new(args[1])
}
}
impl Syscall for SysSetPgid {
fn num_args(&self) -> usize {
2
}
/// # 函数的功能
/// 设置指定进程的pgid
///
/// ## 参数
/// - pid: 指定进程号
/// - pgid: 新的进程组号
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let pid = Self::pid(args);
let pgid = Self::pgid(args);
let current_pcb = ProcessManager::current_pcb();
let pid = if pid == Pid(0) {
current_pcb.pid()
} else {
pid
};
let pgid = if pgid == Pgid::from(0) {
Pgid::from(pid.into())
} else {
pgid
};
if pid != current_pcb.pid() && !current_pcb.contain_child(&pid) {
return Err(SystemError::ESRCH);
}
if pgid.into() != pid.into() && ProcessManager::find_process_group(pgid).is_none() {
return Err(SystemError::EPERM);
}
let pcb = ProcessManager::find(pid).ok_or(SystemError::ESRCH)?;
pcb.join_other_group(pgid)?;
return Ok(0);
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![
FormattedSyscallParam::new("pid", format!("{:#x}", Self::pid(args).0)),
FormattedSyscallParam::new("pgid", format!("{:#x}", Self::pgid(args).0)),
]
}
}
syscall_table_macros::declare_syscall!(SYS_SETPGID, SysSetPgid);

View File

@ -0,0 +1,48 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_SETRESGID;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysSetResGid;
impl SysSetResGid {
fn egid(args: &[usize]) -> usize {
args[1]
}
}
impl Syscall for SysSetResGid {
fn num_args(&self) -> usize {
2
}
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let egid = Self::egid(args);
let pcb = ProcessManager::current_pcb();
let mut guard = pcb.cred.lock();
if egid == usize::MAX || (egid == guard.egid.data() && egid == guard.fsgid.data()) {
return Ok(0);
}
if egid != usize::MAX {
guard.setegid(egid);
}
let egid = guard.egid.data();
guard.setfsgid(egid);
return Ok(0);
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"egid",
format!("{:#x}", Self::egid(args)),
)]
}
}
syscall_table_macros::declare_syscall!(SYS_SETRESGID, SysSetResGid);

View File

@ -0,0 +1,48 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_SETRESUID;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysSetResUid;
impl SysSetResUid {
fn euid(args: &[usize]) -> usize {
args[1]
}
}
impl Syscall for SysSetResUid {
fn num_args(&self) -> usize {
2
}
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let euid = Self::euid(args);
let pcb = ProcessManager::current_pcb();
let mut guard = pcb.cred.lock();
if euid == usize::MAX || (euid == guard.euid.data() && euid == guard.fsuid.data()) {
return Ok(0);
}
if euid != usize::MAX {
guard.seteuid(euid);
}
let euid = guard.euid.data();
guard.setfsuid(euid);
return Ok(0);
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"euid",
format!("{:#x}", Self::euid(args)),
)]
}
}
syscall_table_macros::declare_syscall!(SYS_SETRESUID, SysSetResUid);

View File

@ -0,0 +1,30 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_SETSID;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysSetsid;
impl Syscall for SysSetsid {
fn num_args(&self) -> usize {
0
}
/// # 函数的功能
/// 创建新的会话
fn handle(&self, _args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let pcb = ProcessManager::current_pcb();
let session = pcb.go_to_new_session()?;
let mut guard = pcb.sig_info_mut();
guard.set_tty(None);
Ok(session.sid().into())
}
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![]
}
}
syscall_table_macros::declare_syscall!(SYS_SETSID, SysSetsid);

View File

@ -0,0 +1,47 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_SETUID;
use crate::process::ProcessManager;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysSetUid;
impl SysSetUid {
fn uid(args: &[usize]) -> usize {
args[0]
}
}
impl Syscall for SysSetUid {
fn num_args(&self) -> usize {
1
}
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let uid = Self::uid(args);
let pcb = ProcessManager::current_pcb();
let mut guard = pcb.cred.lock();
if guard.uid.data() == 0 {
guard.setuid(uid);
guard.seteuid(uid);
guard.setsuid(uid);
} else if uid == guard.uid.data() || uid == guard.suid.data() {
guard.seteuid(uid);
} else {
return Err(SystemError::EPERM);
}
return Ok(0);
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"uid",
format!("{:#x}", Self::uid(args)),
)]
}
}
syscall_table_macros::declare_syscall!(SYS_SETUID, SysSetUid);

View File

@ -0,0 +1,38 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_UNAME;
use crate::process::syscall::PosixOldUtsName;
use crate::syscall::table::{FormattedSyscallParam, Syscall};
use crate::syscall::user_access::UserBufferWriter;
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysUname;
impl SysUname {
fn name(args: &[usize]) -> *mut PosixOldUtsName {
args[0] as *mut PosixOldUtsName
}
}
impl Syscall for SysUname {
fn num_args(&self) -> usize {
1
}
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let name = Self::name(args);
let mut writer =
UserBufferWriter::new(name, core::mem::size_of::<PosixOldUtsName>(), true)?;
writer.copy_one_to_user(&PosixOldUtsName::new(), 0)?;
return Ok(0);
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![FormattedSyscallParam::new(
"name",
format!("{:#x}", Self::name(args) as usize),
)]
}
}
syscall_table_macros::declare_syscall!(SYS_UNAME, SysUname);

View File

@ -0,0 +1,35 @@
use crate::arch::interrupt::TrapFrame;
//use crate::arch::syscall::nr::SYS_VFORK;
use crate::process::fork::CloneFlags;
use crate::process::ProcessManager;
use crate::syscall::table::{FormattedSyscallParam, Syscall};
use alloc::vec::Vec;
use system_error::SystemError;
pub struct SysVfork;
impl Syscall for SysVfork {
fn num_args(&self) -> usize {
0
}
fn handle(&self, _args: &[usize], frame: &mut TrapFrame) -> Result<usize, SystemError> {
// 由于Linux vfork需要保证子进程先运行除非子进程调用execve或者exit
// 而我们目前没有实现这个特性所以暂时使用fork代替vforklinux文档表示这样也是也可以的
log::debug!("vfork");
ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into())
// 下面是以前的实现,除非我们实现了子进程先运行的特性,否则不要使用,不然会导致父进程数据损坏
// ProcessManager::fork(
// frame,
// CloneFlags::CLONE_VM | CloneFlags::CLONE_FS | CloneFlags::CLONE_SIGNAL,
// )
// .map(|pid| pid.into())
}
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![]
}
}
//syscall_table_macros::declare_syscall!(SYS_VFORK, SysVfork);

View File

@ -0,0 +1,88 @@
use crate::arch::interrupt::TrapFrame;
use crate::arch::syscall::nr::SYS_WAIT4;
use crate::process::abi::WaitOption;
use crate::process::exit::kernel_wait4;
use crate::process::resource::RUsage;
use crate::syscall::table::FormattedSyscallParam;
use crate::syscall::table::Syscall;
use crate::syscall::user_access::UserBufferWriter;
use alloc::vec::Vec;
use core::ffi::c_int;
use core::ffi::c_void;
use system_error::SystemError;
pub struct SysWait4;
impl SysWait4 {
fn pid(args: &[usize]) -> i32 {
args[0] as i32
}
fn wstatus(args: &[usize]) -> *mut i32 {
args[1] as *mut i32
}
fn options(args: &[usize]) -> c_int {
args[2] as c_int
}
fn rusage(args: &[usize]) -> *mut c_void {
args[3] as *mut c_void
}
}
impl Syscall for SysWait4 {
fn num_args(&self) -> usize {
4
}
fn handle(&self, args: &[usize], _frame: &mut TrapFrame) -> Result<usize, SystemError> {
let pid = Self::pid(args);
let wstatus = Self::wstatus(args);
let options = Self::options(args);
let rusage = Self::rusage(args);
// 权限校验
// todo: 引入rusage之后更正以下权限校验代码中rusage的大小
let options = WaitOption::from_bits(options as u32).ok_or(SystemError::EINVAL)?;
let wstatus_buf = if wstatus.is_null() {
None
} else {
Some(UserBufferWriter::new(
wstatus,
core::mem::size_of::<i32>(),
true,
)?)
};
let mut tmp_rusage = if rusage.is_null() {
None
} else {
Some(RUsage::default())
};
let r = kernel_wait4(pid, wstatus_buf, options, tmp_rusage.as_mut())?;
if !rusage.is_null() {
let mut rusage_buf = UserBufferWriter::new::<RUsage>(
rusage as *mut RUsage,
core::mem::size_of::<RUsage>(),
true,
)?;
rusage_buf.copy_one_to_user(&tmp_rusage.unwrap(), 0)?;
}
return Ok(r);
}
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
vec![
FormattedSyscallParam::new("pid", format!("{:#x}", Self::pid(args))),
FormattedSyscallParam::new("wstatus", format!("{:#x}", Self::wstatus(args) as usize)),
FormattedSyscallParam::new("options", format!("{:#x}", Self::options(args))),
FormattedSyscallParam::new("rusage", format!("{:#x}", Self::rusage(args) as usize)),
]
}
}
syscall_table_macros::declare_syscall!(SYS_WAIT4, SysWait4);

View File

@ -1,5 +1,6 @@
use crate::process::fork::CloneFlags;
use core::{
ffi::{c_int, c_void},
ffi::c_int,
sync::atomic::{AtomicBool, Ordering},
};
@ -9,12 +10,7 @@ use crate::{
libs::{futex::constant::FutexFlag, rand::GRandFlags},
mm::{page::PAGE_4K_SIZE, syscall::MremapFlags},
net::syscall::MsgHdr,
process::{
fork::KernelCloneArgs,
process_group::Pgid,
resource::{RLimit64, RUsage},
ProcessFlags, ProcessManager,
},
process::{ProcessFlags, ProcessManager},
sched::{schedule, SchedMode},
syscall::user_access::check_and_clone_cstr,
};
@ -29,12 +25,10 @@ use crate::{
filesystem::vfs::{
fcntl::{AtFlags, FcntlCommand},
syscall::{ModeType, UtimensFlags},
MAX_PATHLEN,
},
libs::align::page_align_up,
mm::{verify_area, MemoryManagementArch, VirtAddr},
net::syscall::SockAddr,
process::{fork::CloneFlags, syscall::PosixOldUtsName, Pid},
time::{
syscall::{PosixTimeZone, PosixTimeval},
PosixTimeSpec,
@ -106,6 +100,7 @@ impl Syscall {
// handler.name,
// handler.args_string(args)
// );
return handler.inner_handle.handle(args, frame);
}
@ -128,6 +123,11 @@ impl Syscall {
)
}
#[cfg(target_arch = "x86_64")]
SYS_FORK => ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into()),
#[cfg(target_arch = "x86_64")]
SYS_VFORK => ProcessManager::fork(frame, CloneFlags::empty()).map(|pid| pid.into()),
#[cfg(target_arch = "x86_64")]
SYS_RENAMEAT => {
let oldfd = args[0] as i32;
@ -188,11 +188,6 @@ impl Syscall {
Self::pwrite(fd, buf, len, offset)
}
#[cfg(target_arch = "x86_64")]
SYS_FORK => Self::fork(frame),
#[cfg(target_arch = "x86_64")]
SYS_VFORK => Self::vfork(frame),
SYS_BRK => {
let new_brk = VirtAddr::new(args[0]);
Self::brk(new_brk).map(|vaddr| vaddr.data())
@ -243,44 +238,6 @@ impl Syscall {
res
}
SYS_EXECVE => {
let path_ptr = args[0];
let argv_ptr = args[1];
let env_ptr = args[2];
let virt_path_ptr = VirtAddr::new(path_ptr);
let virt_argv_ptr = VirtAddr::new(argv_ptr);
let virt_env_ptr = VirtAddr::new(env_ptr);
// 权限校验
if frame.is_from_user()
&& (verify_area(virt_path_ptr, MAX_PATHLEN).is_err()
|| verify_area(virt_argv_ptr, PAGE_4K_SIZE).is_err())
|| verify_area(virt_env_ptr, PAGE_4K_SIZE).is_err()
{
Err(SystemError::EFAULT)
} else {
Self::execve(
path_ptr as *const u8,
argv_ptr as *const *const u8,
env_ptr as *const *const u8,
frame,
)
.map(|_| 0)
}
}
SYS_WAIT4 => {
let pid = args[0] as i32;
let wstatus = args[1] as *mut i32;
let options = args[2] as c_int;
let rusage = args[3] as *mut c_void;
// 权限校验
// todo: 引入rusage之后更正以下权限校验代码中rusage的大小
Self::wait4(pid, wstatus, options, rusage)
}
SYS_EXIT => {
let exit_code = args[0];
Self::exit(exit_code)
}
#[cfg(target_arch = "x86_64")]
SYS_MKDIR => {
let path = args[0] as *const u8;
@ -360,7 +317,6 @@ impl Syscall {
let path = args[0] as *const u8;
Self::unlink(path)
}
SYS_GETPID => Self::getpid().map(|pid| pid.into()),
SYS_SCHED => {
warn!("syscall sched");
@ -604,10 +560,6 @@ impl Syscall {
}
}
SYS_GETPGID => Self::getpgid(Pid::new(args[0])).map(|pgid| pgid.into()),
SYS_GETPPID => Self::getppid().map(|pid| pid.into()),
SYS_FCNTL => {
let fd = args[0] as i32;
let cmd: Option<FcntlCommand> =
@ -644,23 +596,6 @@ impl Syscall {
)
}
SYS_CLONE => {
let parent_tid = VirtAddr::new(args[2]);
let child_tid = VirtAddr::new(args[3]);
// 地址校验
verify_area(parent_tid, core::mem::size_of::<i32>())?;
verify_area(child_tid, core::mem::size_of::<i32>())?;
let mut clone_args = KernelCloneArgs::new();
clone_args.flags = CloneFlags::from_bits_truncate(args[0] as u64);
clone_args.stack = args[1];
clone_args.parent_tid = parent_tid;
clone_args.child_tid = child_tid;
clone_args.tls = args[4];
Self::clone(frame, clone_args)
}
SYS_FUTEX => {
let uaddr = VirtAddr::new(args[0]);
let operation = FutexFlag::from_bits(args[1] as u32).ok_or(SystemError::ENOSYS)?;
@ -703,8 +638,6 @@ impl Syscall {
return ret;
}
SYS_SET_TID_ADDRESS => Self::set_tid_address(args[0]),
SYS_STATFS => {
let path = args[0] as *const u8;
let statfs = args[1] as *mut PosixStatfs;
@ -751,12 +684,6 @@ impl Syscall {
SYS_PPOLL => Self::ppoll(args[0], args[1] as u32, args[2], args[3]),
SYS_SETPGID => {
let pid = Pid::new(args[0]);
let pgid = Pgid::new(args[1]);
Self::setpgid(pid, pgid)
}
SYS_TKILL => {
warn!("SYS_TKILL has not yet been implemented");
Ok(0)
@ -767,13 +694,6 @@ impl Syscall {
Ok(0)
}
SYS_EXIT_GROUP => {
let exit_code = args[0];
Self::exit(exit_code)
// warn!("SYS_EXIT_GROUP has not yet been implemented");
// Ok(0)
}
SYS_MADVISE => {
let addr = args[0];
let len = page_align_up(args[1]);
@ -784,8 +704,6 @@ impl Syscall {
}
}
SYS_GETTID => Self::gettid().map(|tid| tid.into()),
SYS_SYSLOG => {
let syslog_action_type = args[0];
let buf_vaddr = args[1];
@ -798,27 +716,6 @@ impl Syscall {
Self::do_syslog(syslog_action_type, user_buf, len)
}
SYS_GETUID => Self::getuid(),
SYS_GETGID => Self::getgid(),
SYS_SETUID => Self::setuid(args[0]),
SYS_SETGID => Self::setgid(args[0]),
SYS_GETEUID => Self::geteuid(),
SYS_GETEGID => Self::getegid(),
SYS_SETRESUID => Self::seteuid(args[1]),
SYS_SETRESGID => Self::setegid(args[1]),
SYS_SETFSUID => Self::setfsuid(args[0]),
SYS_SETFSGID => Self::setfsgid(args[0]),
SYS_SETSID => Self::setsid(),
SYS_GETSID => Self::getsid(Pid::new(args[0])),
SYS_GETRUSAGE => {
let who = args[0] as c_int;
let rusage = args[1] as *mut RUsage;
Self::get_rusage(who, rusage)
}
#[cfg(target_arch = "x86_64")]
SYS_READLINK => {
let path = args[0] as *const u8;
@ -835,16 +732,6 @@ impl Syscall {
Self::readlink_at(dirfd, path, buf, bufsiz)
}
SYS_PRLIMIT64 => {
let pid = args[0];
let pid = Pid::new(pid);
let resource = args[1];
let new_limit = args[2] as *const RLimit64;
let old_limit = args[3] as *mut RLimit64;
Self::prlimit64(pid, resource, new_limit, old_limit)
}
#[cfg(target_arch = "x86_64")]
SYS_ACCESS => {
let pathname = args[0] as *const u8;
@ -954,19 +841,6 @@ impl Syscall {
Self::getaffinity(pid, set)
}
#[cfg(target_arch = "x86_64")]
SYS_GETRLIMIT => {
let resource = args[0];
let rlimit = args[1] as *mut RLimit64;
Self::prlimit64(
ProcessManager::current_pcb().pid(),
resource,
core::ptr::null::<RLimit64>(),
rlimit,
)
}
SYS_FADVISE64 => {
// todo: 这个系统调用还没有实现
@ -993,10 +867,6 @@ impl Syscall {
SYS_NEWFSTATAT => Self::newfstatat(args[0] as i32, args[1], args[2], args[3] as u32),
// SYS_SCHED_YIELD => Self::sched_yield(),
SYS_UNAME => {
let name = args[0] as *mut PosixOldUtsName;
Self::uname(name)
}
SYS_PRCTL => {
// todo: 这个系统调用还没有实现