mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 14:16:47 +00:00
refactor(ipc): Refactor the syscalls in ipc (#1183)
* feat(ipc): 完成对ipc的系统调用的重构 * refactor(ipc): 优化结构 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * feat: fmt Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> --------- Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> Co-authored-by: Vitus <zhzvitus@gmail.com> Co-authored-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
This commit is contained in:
parent
6ac8e1f0cd
commit
5db1f9ad54
@ -20,7 +20,7 @@ use crate::{
|
||||
mm::MemoryManagementArch,
|
||||
process::ProcessManager,
|
||||
sched::{schedule, SchedMode},
|
||||
syscall::{user_access::UserBufferWriter, Syscall},
|
||||
syscall::user_access::UserBufferWriter,
|
||||
};
|
||||
|
||||
/// 信号处理的栈的栈指针的最小对齐数量
|
||||
@ -556,7 +556,10 @@ impl SignalArch for X86_64SignalArch {
|
||||
// 如果当前的rsp不来自用户态,则认为产生了错误(或被SROP攻击)
|
||||
if UserBufferWriter::new(frame, size_of::<SigFrame>(), true).is_err() {
|
||||
error!("rsp doesn't from user level");
|
||||
let _r = Syscall::kill_process(ProcessManager::current_pcb().pid(), Signal::SIGSEGV)
|
||||
let _r = crate::ipc::kill::kill_process(
|
||||
ProcessManager::current_pcb().pid(),
|
||||
Signal::SIGSEGV,
|
||||
)
|
||||
.map_err(|e| e.to_posix_errno());
|
||||
return trap_frame.rax;
|
||||
}
|
||||
@ -565,7 +568,10 @@ impl SignalArch for X86_64SignalArch {
|
||||
// 从用户栈恢复sigcontext
|
||||
if !unsafe { &mut (*frame).context }.restore_sigcontext(trap_frame) {
|
||||
error!("unable to restore sigcontext");
|
||||
let _r = Syscall::kill_process(ProcessManager::current_pcb().pid(), Signal::SIGSEGV)
|
||||
let _r = crate::ipc::kill::kill_process(
|
||||
ProcessManager::current_pcb().pid(),
|
||||
Signal::SIGSEGV,
|
||||
)
|
||||
.map_err(|e| e.to_posix_errno());
|
||||
// 如果这里返回 err 值的话会丢失上一个系统调用的返回值
|
||||
}
|
||||
@ -658,7 +664,7 @@ fn setup_frame(
|
||||
ProcessManager::current_pcb().pid(),
|
||||
sig as i32
|
||||
);
|
||||
let r = Syscall::kill_process(
|
||||
let r = crate::ipc::kill::kill_process(
|
||||
ProcessManager::current_pcb().pid(),
|
||||
Signal::SIGSEGV,
|
||||
);
|
||||
@ -698,7 +704,8 @@ fn setup_frame(
|
||||
if r.is_err() {
|
||||
// 如果地址区域位于内核空间,则直接报错
|
||||
// todo: 生成一个sigsegv
|
||||
let r = Syscall::kill_process(ProcessManager::current_pcb().pid(), Signal::SIGSEGV);
|
||||
let r =
|
||||
crate::ipc::kill::kill_process(ProcessManager::current_pcb().pid(), Signal::SIGSEGV);
|
||||
if r.is_err() {
|
||||
error!("In setup frame: generate SIGSEGV signal failed");
|
||||
}
|
||||
@ -709,7 +716,10 @@ fn setup_frame(
|
||||
// 将siginfo拷贝到用户栈
|
||||
info.copy_siginfo_to_user(unsafe { &mut ((*frame).info) as *mut SigInfo })
|
||||
.map_err(|e| -> SystemError {
|
||||
let r = Syscall::kill_process(ProcessManager::current_pcb().pid(), Signal::SIGSEGV);
|
||||
let r = crate::ipc::kill::kill_process(
|
||||
ProcessManager::current_pcb().pid(),
|
||||
Signal::SIGSEGV,
|
||||
);
|
||||
if r.is_err() {
|
||||
error!("In copy_siginfo_to_user: generate SIGSEGV signal failed");
|
||||
}
|
||||
@ -723,7 +733,10 @@ fn setup_frame(
|
||||
.context
|
||||
.setup_sigcontext(oldset, trap_frame)
|
||||
.map_err(|e: SystemError| -> SystemError {
|
||||
let r = Syscall::kill_process(ProcessManager::current_pcb().pid(), Signal::SIGSEGV);
|
||||
let r = crate::ipc::kill::kill_process(
|
||||
ProcessManager::current_pcb().pid(),
|
||||
Signal::SIGSEGV,
|
||||
);
|
||||
if r.is_err() {
|
||||
error!("In setup_sigcontext: generate SIGSEGV signal failed");
|
||||
}
|
||||
|
@ -5,10 +5,7 @@ use crate::{
|
||||
arch::ipc::signal::{SigSet, Signal},
|
||||
mm::VirtAddr,
|
||||
process::{process_group::Pgid, Pid, ProcessFlags, ProcessManager},
|
||||
syscall::{
|
||||
user_access::{UserBufferReader, UserBufferWriter},
|
||||
Syscall,
|
||||
},
|
||||
syscall::user_access::{UserBufferReader, UserBufferWriter},
|
||||
};
|
||||
|
||||
use super::tty_core::{TtyCore, TtyIoctlCmd};
|
||||
@ -59,7 +56,7 @@ impl TtyJobCtrlManager {
|
||||
} else if ProcessManager::is_current_pgrp_orphaned() {
|
||||
return Err(SystemError::EIO);
|
||||
} else {
|
||||
Syscall::kill_process_group(pgid, sig)?;
|
||||
crate::ipc::kill::kill_process_group(pgid, sig)?;
|
||||
ProcessManager::current_pcb()
|
||||
.flags()
|
||||
.insert(ProcessFlags::HAS_PENDING_SIGNAL);
|
||||
|
@ -22,7 +22,7 @@ use crate::{
|
||||
},
|
||||
mm::VirtAddr,
|
||||
process::{ProcessFlags, ProcessManager},
|
||||
syscall::{user_access::UserBufferWriter, Syscall},
|
||||
syscall::user_access::UserBufferWriter,
|
||||
};
|
||||
|
||||
use super::TtyLineDiscipline;
|
||||
@ -789,7 +789,7 @@ impl NTtyData {
|
||||
let ctrl_info = tty.core().contorl_info_irqsave();
|
||||
let pg = ctrl_info.pgid;
|
||||
if let Some(pg) = pg {
|
||||
let _ = Syscall::kill_process_group(pg, signal);
|
||||
let _ = crate::ipc::kill::kill_process_group(pg, signal);
|
||||
}
|
||||
|
||||
if !termios.local_mode.contains(LocalMode::NOFLSH) {
|
||||
|
44
kernel/src/ipc/kill.rs
Normal file
44
kernel/src/ipc/kill.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use crate::arch::ipc::signal::{SigCode, Signal};
|
||||
use crate::ipc::signal_types::{SigInfo, SigType};
|
||||
use crate::process::{process_group::Pgid, Pid, ProcessManager};
|
||||
use core::sync::atomic::compiler_fence;
|
||||
use system_error::SystemError;
|
||||
|
||||
/// ### 杀死一个进程
|
||||
pub fn kill_process(pid: Pid, sig: Signal) -> Result<usize, SystemError> {
|
||||
// 初始化signal info
|
||||
let mut info = SigInfo::new(sig, 0, SigCode::User, SigType::Kill(pid));
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
let ret = sig
|
||||
.send_signal_info(Some(&mut info), pid)
|
||||
.map(|x| x as usize);
|
||||
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
ret
|
||||
}
|
||||
|
||||
/// ### 杀死一个进程组
|
||||
pub fn kill_process_group(pgid: Pgid, sig: Signal) -> Result<usize, SystemError> {
|
||||
let pg = ProcessManager::find_process_group(pgid).ok_or(SystemError::ESRCH)?;
|
||||
let inner = pg.process_group_inner.lock();
|
||||
for pcb in inner.processes.values() {
|
||||
kill_process(pcb.pid(), sig)?; // Call the new common function
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
/// ### 杀死所有进程
|
||||
/// - 该函数会杀死所有进程,除了当前进程和init进程
|
||||
pub fn kill_all(sig: Signal) -> Result<usize, SystemError> {
|
||||
let current_pid = ProcessManager::current_pcb().pid();
|
||||
let all_processes = ProcessManager::get_all_processes();
|
||||
|
||||
for pid_val in all_processes {
|
||||
if pid_val == current_pid || pid_val.data() == 1 {
|
||||
continue;
|
||||
}
|
||||
kill_process(pid_val, sig)?; // Call the new common function
|
||||
}
|
||||
Ok(0)
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
pub mod generic_signal;
|
||||
pub mod kill;
|
||||
pub mod pipe;
|
||||
pub mod shm;
|
||||
pub mod signal;
|
||||
|
@ -14,13 +14,13 @@ use crate::{
|
||||
syscall::user_access::{UserBufferReader, UserBufferWriter},
|
||||
time::PosixTimeSpec,
|
||||
};
|
||||
use core::fmt;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use hashbrown::HashMap;
|
||||
use ida::IdAllocator;
|
||||
use log::info;
|
||||
use num::ToPrimitive;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub static mut SHM_MANAGER: Option<SpinLock<ShmManager>> = None;
|
||||
|
||||
/// 用于创建新的私有IPC对象
|
||||
@ -104,6 +104,23 @@ impl From<usize> for ShmCtlCmd {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ShmCtlCmd {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ShmCtlCmd::IpcRmid => write!(f, "IPC_RMID"),
|
||||
ShmCtlCmd::IpcSet => write!(f, "IPC_SET"),
|
||||
ShmCtlCmd::IpcStat => write!(f, "IPC_STAT"),
|
||||
ShmCtlCmd::IpcInfo => write!(f, "IPC_INFO"),
|
||||
ShmCtlCmd::ShmLock => write!(f, "SHM_LOCK"),
|
||||
ShmCtlCmd::ShmUnlock => write!(f, "SHM_UNLOCK"),
|
||||
ShmCtlCmd::ShmStat => write!(f, "SHM_STAT"),
|
||||
ShmCtlCmd::ShmInfo => write!(f, "SHM_INFO"),
|
||||
ShmCtlCmd::ShmtStatAny => write!(f, "SHM_STAT_ANY"),
|
||||
ShmCtlCmd::Default => write!(f, "DEFAULT (Invalid Cmd)"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for ShmCtlCmd {
|
||||
fn eq(&self, other: &ShmCtlCmd) -> bool {
|
||||
*self as usize == *other as usize
|
||||
|
@ -1,662 +0,0 @@
|
||||
use core::{
|
||||
ffi::{c_int, c_void},
|
||||
sync::atomic::compiler_fence,
|
||||
};
|
||||
|
||||
use log::{error, warn};
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::{
|
||||
ipc::signal::{SigCode, SigFlags, SigSet, Signal},
|
||||
MMArch,
|
||||
},
|
||||
filesystem::vfs::{
|
||||
file::{File, FileMode},
|
||||
FilePrivateData,
|
||||
},
|
||||
ipc::shm::{shm_manager_lock, IPC_PRIVATE},
|
||||
libs::{align::page_align_up, spinlock::SpinLock},
|
||||
mm::{
|
||||
allocator::page_frame::{PageFrameCount, PhysPageFrame, VirtPageFrame},
|
||||
page::{page_manager_lock_irqsave, EntryFlags, PageFlushAll},
|
||||
syscall::ProtFlags,
|
||||
ucontext::{AddressSpace, VMA},
|
||||
VirtAddr, VmFlags,
|
||||
},
|
||||
process::{process_group::Pgid, Pid, ProcessManager},
|
||||
syscall::{
|
||||
user_access::{UserBufferReader, UserBufferWriter},
|
||||
Syscall,
|
||||
},
|
||||
};
|
||||
|
||||
use super::{
|
||||
pipe::{LockedPipeInode, PipeFsPrivateData},
|
||||
shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey},
|
||||
signal::{set_sigprocmask, SigHow},
|
||||
signal_types::{
|
||||
SaHandlerType, SigInfo, SigType, Sigaction, SigactionType, UserSigaction, USER_SIG_DFL,
|
||||
USER_SIG_ERR, USER_SIG_IGN,
|
||||
},
|
||||
};
|
||||
|
||||
/// ### pid转换器,将输入的id转换成对应的pid或pgid
|
||||
/// - 如果id < -1,则为pgid
|
||||
/// - 如果id == -1,则为所有进程
|
||||
/// - 如果id == 0,则为当前进程组
|
||||
/// - 如果id > 0,则为pid
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum PidConverter {
|
||||
All,
|
||||
Pid(Pid),
|
||||
Pgid(Pgid),
|
||||
}
|
||||
|
||||
impl PidConverter {
|
||||
/// ### 为 `wait` 和 `kill` 调用使用
|
||||
pub fn from_id(id: i32) -> Self {
|
||||
if id < -1 {
|
||||
PidConverter::Pgid(Pgid::from(-id as usize))
|
||||
} else if id == -1 {
|
||||
PidConverter::All
|
||||
} else if id == 0 {
|
||||
let pgid = ProcessManager::current_pcb().pgid();
|
||||
PidConverter::Pgid(pgid)
|
||||
} else {
|
||||
PidConverter::Pid(Pid::from(id as usize))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall {
|
||||
/// # 创建带参数的匿名管道
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `fd`: 用于返回文件描述符的数组
|
||||
/// - `flags`:设置管道的参数
|
||||
pub fn pipe2(fd: *mut i32, flags: FileMode) -> Result<usize, SystemError> {
|
||||
if !flags
|
||||
.difference(FileMode::O_CLOEXEC | FileMode::O_NONBLOCK | FileMode::O_DIRECT)
|
||||
.is_empty()
|
||||
{
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let mut user_buffer = UserBufferWriter::new(fd, core::mem::size_of::<[c_int; 2]>(), true)?;
|
||||
let fd = user_buffer.buffer::<i32>(0)?;
|
||||
let pipe_ptr = LockedPipeInode::new();
|
||||
|
||||
let mut read_file = File::new(
|
||||
pipe_ptr.clone(),
|
||||
FileMode::O_RDONLY | (flags & FileMode::O_NONBLOCK),
|
||||
)?;
|
||||
read_file.private_data = SpinLock::new(FilePrivateData::Pipefs(PipeFsPrivateData::new(
|
||||
FileMode::O_RDONLY,
|
||||
)));
|
||||
|
||||
let mut write_file = File::new(
|
||||
pipe_ptr.clone(),
|
||||
FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)),
|
||||
)?;
|
||||
write_file.private_data = SpinLock::new(FilePrivateData::Pipefs(PipeFsPrivateData::new(
|
||||
FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)),
|
||||
)));
|
||||
|
||||
if flags.contains(FileMode::O_CLOEXEC) {
|
||||
read_file.set_close_on_exec(true);
|
||||
write_file.set_close_on_exec(true);
|
||||
}
|
||||
let fd_table_ptr = ProcessManager::current_pcb().fd_table();
|
||||
let mut fd_table_guard = fd_table_ptr.write();
|
||||
let read_fd = fd_table_guard.alloc_fd(read_file, None)?;
|
||||
let write_fd = fd_table_guard.alloc_fd(write_file, None)?;
|
||||
|
||||
drop(fd_table_guard);
|
||||
|
||||
fd[0] = read_fd;
|
||||
fd[1] = write_fd;
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
/// ### 杀死一个进程
|
||||
pub fn kill_process(pid: Pid, sig: Signal) -> Result<usize, SystemError> {
|
||||
// 初始化signal info
|
||||
let mut info = SigInfo::new(sig, 0, SigCode::User, SigType::Kill(pid));
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
let ret = sig
|
||||
.send_signal_info(Some(&mut info), pid)
|
||||
.map(|x| x as usize);
|
||||
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// ### 杀死一个进程组
|
||||
pub fn kill_process_group(pgid: Pgid, sig: Signal) -> Result<usize, SystemError> {
|
||||
let pg = ProcessManager::find_process_group(pgid).ok_or(SystemError::ESRCH)?;
|
||||
let inner = pg.process_group_inner.lock();
|
||||
for pcb in inner.processes.values() {
|
||||
Self::kill_process(pcb.pid(), sig)?;
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
/// ### 杀死所有进程
|
||||
/// - 该函数会杀死所有进程,除了当前进程和init进程
|
||||
pub fn kill_all(sig: Signal) -> Result<usize, SystemError> {
|
||||
let current_pid = ProcessManager::current_pcb().pid();
|
||||
let all_processes = ProcessManager::get_all_processes();
|
||||
|
||||
for pid in all_processes {
|
||||
if pid == current_pid || pid.data() == 1 {
|
||||
continue;
|
||||
}
|
||||
Self::kill_process(pid, sig)?;
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
/// # kill系统调用函数
|
||||
///
|
||||
/// ## 参数
|
||||
/// - `id`: id,等于0表示当前进程组,等于-1表示所有进程,小于0表示pgid = -id,大于0表示pid = id,
|
||||
/// - `sig`: 信号值
|
||||
pub fn kill(id: i32, sig: c_int) -> Result<usize, SystemError> {
|
||||
let converter = PidConverter::from_id(id);
|
||||
let sig = Signal::from(sig);
|
||||
if sig == Signal::INVALID {
|
||||
// 传入的signal数值不合法
|
||||
warn!("Not a valid signal number");
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
// compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
let retval = match converter {
|
||||
PidConverter::Pid(pid) => Self::kill_process(pid, sig),
|
||||
PidConverter::Pgid(pgid) => Self::kill_process_group(pgid, sig),
|
||||
PidConverter::All => Self::kill_all(sig),
|
||||
};
|
||||
|
||||
// compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/// 通用信号注册函数
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `sig` 信号的值
|
||||
/// - `act` 用户空间传入的 Sigaction 指针
|
||||
/// - `old_act` 用户空间传入的用来保存旧 Sigaction 的指针
|
||||
/// - `from_user` 用来标识这个函数调用是否来自用户空间
|
||||
///
|
||||
/// @return int 错误码
|
||||
#[no_mangle]
|
||||
pub fn sigaction(
|
||||
sig: c_int,
|
||||
new_act: usize,
|
||||
old_act: usize,
|
||||
from_user: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
// 请注意:用户态传进来的user_sigaction结构体类型,请注意,这个结构体与内核实际的不一样
|
||||
let act: *mut UserSigaction = new_act as *mut UserSigaction;
|
||||
let old_act = old_act as *mut UserSigaction;
|
||||
let mut new_ka: Sigaction = Default::default();
|
||||
let mut old_sigaction: Sigaction = Default::default();
|
||||
// 如果传入的,新的sigaction不为空
|
||||
if !act.is_null() {
|
||||
// 如果参数的范围不在用户空间,则返回错误
|
||||
let r = UserBufferWriter::new(act, core::mem::size_of::<Sigaction>(), from_user);
|
||||
if r.is_err() {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
let mask: SigSet = unsafe { (*act).mask };
|
||||
let input_sighandler = unsafe { (*act).handler as u64 };
|
||||
match input_sighandler {
|
||||
USER_SIG_DFL => {
|
||||
new_ka = Sigaction::DEFAULT_SIGACTION;
|
||||
*new_ka.flags_mut() = unsafe { (*act).flags };
|
||||
new_ka.set_restorer(None);
|
||||
}
|
||||
|
||||
USER_SIG_IGN => {
|
||||
new_ka = Sigaction::DEFAULT_SIGACTION_IGNORE;
|
||||
*new_ka.flags_mut() = unsafe { (*act).flags };
|
||||
|
||||
new_ka.set_restorer(None);
|
||||
}
|
||||
_ => {
|
||||
// 从用户空间获得sigaction结构体
|
||||
// TODO mask是default还是用户空间传入
|
||||
new_ka = Sigaction::new(
|
||||
SigactionType::SaHandler(SaHandlerType::Customized(unsafe {
|
||||
VirtAddr::new((*act).handler as usize)
|
||||
})),
|
||||
unsafe { (*act).flags },
|
||||
SigSet::default(),
|
||||
unsafe { Some(VirtAddr::new((*act).restorer as usize)) },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 如果为空,赋默认值?
|
||||
// debug!("new_ka={:?}", new_ka);
|
||||
// 如果用户手动给了sa_restorer,那么就置位SA_FLAG_RESTORER,否则报错。(用户必须手动指定restorer)
|
||||
if new_ka.restorer().is_some() {
|
||||
new_ka.flags_mut().insert(SigFlags::SA_RESTORER);
|
||||
} else if new_ka.action().is_customized() {
|
||||
error!(
|
||||
"pid:{:?}: in sys_sigaction: User must manually sprcify a sa_restorer for signal {}.",
|
||||
ProcessManager::current_pcb().pid(),
|
||||
sig
|
||||
);
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
*new_ka.mask_mut() = mask;
|
||||
}
|
||||
|
||||
let sig = Signal::from(sig);
|
||||
// 如果给出的信号值不合法
|
||||
if sig == Signal::INVALID {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let retval = super::signal::do_sigaction(
|
||||
sig,
|
||||
if act.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&mut new_ka)
|
||||
},
|
||||
if old_act.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&mut old_sigaction)
|
||||
},
|
||||
);
|
||||
|
||||
//
|
||||
if (retval == Ok(())) && (!old_act.is_null()) {
|
||||
let r =
|
||||
UserBufferWriter::new(old_act, core::mem::size_of::<UserSigaction>(), from_user);
|
||||
if r.is_err() {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
|
||||
let sigaction_handler = match old_sigaction.action() {
|
||||
SigactionType::SaHandler(handler) => {
|
||||
if let SaHandlerType::Customized(hand) = handler {
|
||||
hand
|
||||
} else if handler.is_sig_ignore() {
|
||||
VirtAddr::new(USER_SIG_IGN as usize)
|
||||
} else if handler.is_sig_error() {
|
||||
VirtAddr::new(USER_SIG_ERR as usize)
|
||||
} else {
|
||||
VirtAddr::new(USER_SIG_DFL as usize)
|
||||
}
|
||||
}
|
||||
SigactionType::SaSigaction(_) => {
|
||||
error!("unsupported type: SaSigaction");
|
||||
VirtAddr::new(USER_SIG_DFL as usize)
|
||||
}
|
||||
};
|
||||
|
||||
unsafe {
|
||||
(*old_act).handler = sigaction_handler.data() as *mut c_void;
|
||||
(*old_act).flags = old_sigaction.flags();
|
||||
(*old_act).mask = old_sigaction.mask();
|
||||
if old_sigaction.restorer().is_some() {
|
||||
(*old_act).restorer = old_sigaction.restorer().unwrap().data() as *mut c_void;
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval.map(|_| 0);
|
||||
}
|
||||
|
||||
/// # SYS_SHMGET系统调用函数,用于获取共享内存
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `key`: 共享内存键值
|
||||
/// - `size`: 共享内存大小(bytes)
|
||||
/// - `shmflg`: 共享内存标志
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:共享内存id
|
||||
/// 失败:错误码
|
||||
pub fn shmget(key: ShmKey, size: usize, shmflg: ShmFlags) -> Result<usize, SystemError> {
|
||||
// 暂不支持巨页
|
||||
if shmflg.contains(ShmFlags::SHM_HUGETLB) {
|
||||
error!("shmget: not support huge page");
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
|
||||
let mut shm_manager_guard = shm_manager_lock();
|
||||
match key {
|
||||
// 创建共享内存段
|
||||
IPC_PRIVATE => shm_manager_guard.add(key, size, shmflg),
|
||||
_ => {
|
||||
// 查找key对应的共享内存段是否存在
|
||||
let id = shm_manager_guard.contains_key(&key);
|
||||
if let Some(id) = id {
|
||||
// 不能重复创建
|
||||
if shmflg.contains(ShmFlags::IPC_CREAT | ShmFlags::IPC_EXCL) {
|
||||
return Err(SystemError::EEXIST);
|
||||
}
|
||||
|
||||
// key值存在,说明有对应共享内存,返回该共享内存id
|
||||
return Ok(id.data());
|
||||
} else {
|
||||
// key不存在且shm_flags不包含IPC_CREAT创建IPC对象标志,则返回错误码
|
||||
if !shmflg.contains(ShmFlags::IPC_CREAT) {
|
||||
return Err(SystemError::ENOENT);
|
||||
}
|
||||
|
||||
// 存在创建IPC对象标志
|
||||
return shm_manager_guard.add(key, size, shmflg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// # SYS_SHMAT系统调用函数,用于连接共享内存段
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `id`: 共享内存id
|
||||
/// - `vaddr`: 连接共享内存的进程虚拟内存区域起始地址
|
||||
/// - `shmflg`: 共享内存标志
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:映射到共享内存的虚拟内存区域起始地址
|
||||
/// 失败:错误码
|
||||
pub fn shmat(id: ShmId, vaddr: VirtAddr, shmflg: ShmFlags) -> Result<usize, SystemError> {
|
||||
let mut shm_manager_guard = shm_manager_lock();
|
||||
let current_address_space = AddressSpace::current()?;
|
||||
let mut address_write_guard = current_address_space.write();
|
||||
|
||||
let kernel_shm = shm_manager_guard.get_mut(&id).ok_or(SystemError::EINVAL)?;
|
||||
let size = page_align_up(kernel_shm.size());
|
||||
let mut phys = PhysPageFrame::new(kernel_shm.start_paddr());
|
||||
let count = PageFrameCount::from_bytes(size).unwrap();
|
||||
let r = match vaddr.data() {
|
||||
// 找到空闲区域并映射到共享内存
|
||||
0 => {
|
||||
// 找到空闲区域
|
||||
let region = address_write_guard
|
||||
.mappings
|
||||
.find_free(vaddr, size)
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
let vm_flags = VmFlags::from(shmflg);
|
||||
let destination = VirtPageFrame::new(region.start());
|
||||
let page_flags: EntryFlags<MMArch> =
|
||||
EntryFlags::from_prot_flags(ProtFlags::from(vm_flags), true);
|
||||
let flusher: PageFlushAll<MMArch> = PageFlushAll::new();
|
||||
|
||||
// 将共享内存映射到对应虚拟区域
|
||||
let vma = VMA::physmap(
|
||||
phys,
|
||||
destination,
|
||||
count,
|
||||
vm_flags,
|
||||
page_flags,
|
||||
&mut address_write_guard.user_mapper.utable,
|
||||
flusher,
|
||||
)?;
|
||||
|
||||
// 将VMA加入到当前进程的VMA列表中
|
||||
address_write_guard.mappings.insert_vma(vma);
|
||||
|
||||
region.start().data()
|
||||
}
|
||||
// 指定虚拟地址
|
||||
_ => {
|
||||
// 获取对应vma
|
||||
let vma = address_write_guard
|
||||
.mappings
|
||||
.contains(vaddr)
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
if vma.lock_irqsave().region().start() != vaddr {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
// 验证用户虚拟内存区域是否有效
|
||||
let _ = UserBufferReader::new(vaddr.data() as *const u8, size, true)?;
|
||||
|
||||
// 必须在取消映射前获取到EntryFlags
|
||||
let page_flags = address_write_guard
|
||||
.user_mapper
|
||||
.utable
|
||||
.translate(vaddr)
|
||||
.ok_or(SystemError::EINVAL)?
|
||||
.1;
|
||||
|
||||
// 取消原映射
|
||||
let flusher: PageFlushAll<MMArch> = PageFlushAll::new();
|
||||
vma.unmap(&mut address_write_guard.user_mapper.utable, flusher);
|
||||
|
||||
// 将该虚拟内存区域映射到共享内存区域
|
||||
let mut page_manager_guard = page_manager_lock_irqsave();
|
||||
let mut virt = VirtPageFrame::new(vaddr);
|
||||
for _ in 0..count.data() {
|
||||
let r = unsafe {
|
||||
address_write_guard.user_mapper.utable.map_phys(
|
||||
virt.virt_address(),
|
||||
phys.phys_address(),
|
||||
page_flags,
|
||||
)
|
||||
}
|
||||
.expect("Failed to map zero, may be OOM error");
|
||||
r.flush();
|
||||
|
||||
// 将vma加入到对应Page的anon_vma
|
||||
page_manager_guard
|
||||
.get_unwrap(&phys.phys_address())
|
||||
.write_irqsave()
|
||||
.insert_vma(vma.clone());
|
||||
|
||||
phys = phys.next();
|
||||
virt = virt.next();
|
||||
}
|
||||
|
||||
// 更新vma的映射状态
|
||||
vma.lock_irqsave().set_mapped(true);
|
||||
|
||||
vaddr.data()
|
||||
}
|
||||
};
|
||||
|
||||
// 更新最后一次连接时间
|
||||
kernel_shm.update_atim();
|
||||
|
||||
// 映射计数增加
|
||||
kernel_shm.increase_count();
|
||||
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
/// # SYS_SHMDT系统调用函数,用于取消对共享内存的连接
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `vaddr`: 需要取消映射的虚拟内存区域起始地址
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:0
|
||||
/// 失败:错误码
|
||||
pub fn shmdt(vaddr: VirtAddr) -> Result<usize, SystemError> {
|
||||
let current_address_space = AddressSpace::current()?;
|
||||
let mut address_write_guard = current_address_space.write();
|
||||
|
||||
// 获取vma
|
||||
let vma = address_write_guard
|
||||
.mappings
|
||||
.contains(vaddr)
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
|
||||
// 判断vaddr是否为起始地址
|
||||
if vma.lock_irqsave().region().start() != vaddr {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
// 取消映射
|
||||
let flusher: PageFlushAll<MMArch> = PageFlushAll::new();
|
||||
vma.unmap(&mut address_write_guard.user_mapper.utable, flusher);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
/// # SYS_SHMCTL系统调用函数,用于管理共享内存段
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `id`: 共享内存id
|
||||
/// - `cmd`: 操作码
|
||||
/// - `user_buf`: 用户缓冲区
|
||||
/// - `from_user`: buf_vaddr是否来自用户地址空间
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:0
|
||||
/// 失败:错误码
|
||||
pub fn shmctl(
|
||||
id: ShmId,
|
||||
cmd: ShmCtlCmd,
|
||||
user_buf: *const u8,
|
||||
from_user: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
let mut shm_manager_guard = shm_manager_lock();
|
||||
|
||||
match cmd {
|
||||
// 查看共享内存元信息
|
||||
ShmCtlCmd::IpcInfo => shm_manager_guard.ipc_info(user_buf, from_user),
|
||||
// 查看共享内存使用信息
|
||||
ShmCtlCmd::ShmInfo => shm_manager_guard.shm_info(user_buf, from_user),
|
||||
// 查看id对应的共享内存信息
|
||||
ShmCtlCmd::ShmStat | ShmCtlCmd::ShmtStatAny | ShmCtlCmd::IpcStat => {
|
||||
shm_manager_guard.shm_stat(id, cmd, user_buf, from_user)
|
||||
}
|
||||
// 设置KernIpcPerm
|
||||
ShmCtlCmd::IpcSet => shm_manager_guard.ipc_set(id, user_buf, from_user),
|
||||
// 将共享内存段设置为可回收状态
|
||||
ShmCtlCmd::IpcRmid => shm_manager_guard.ipc_rmid(id),
|
||||
// 锁住共享内存段,不允许内存置换
|
||||
ShmCtlCmd::ShmLock => shm_manager_guard.shm_lock(id),
|
||||
// 解锁共享内存段,允许内存置换
|
||||
ShmCtlCmd::ShmUnlock => shm_manager_guard.shm_unlock(id),
|
||||
// 无效操作码
|
||||
ShmCtlCmd::Default => Err(SystemError::EINVAL),
|
||||
}
|
||||
}
|
||||
|
||||
/// # SYS_SIGPROCMASK系统调用函数,用于设置或查询当前进程的信号屏蔽字
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `how`: 指示如何修改信号屏蔽字
|
||||
/// - `nset`: 新的信号屏蔽字
|
||||
/// - `oset`: 旧的信号屏蔽字的指针,由于可以是NULL,所以用Option包装
|
||||
/// - `sigsetsize`: 信号集的大小
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:0
|
||||
/// 失败:错误码
|
||||
///
|
||||
/// ## 说明
|
||||
/// 根据 https://man7.org/linux/man-pages/man2/sigprocmask.2.html ,传进来的oldset和newset都是指针类型,这里选择传入usize然后转换为u64的指针类型
|
||||
pub fn rt_sigprocmask(
|
||||
how: i32,
|
||||
newset: usize,
|
||||
oldset: usize,
|
||||
sigsetsize: usize,
|
||||
) -> Result<usize, SystemError> {
|
||||
// 对应oset传进来一个NULL的情况
|
||||
let oset = if oldset == 0 { None } else { Some(oldset) };
|
||||
let nset = if newset == 0 { None } else { Some(newset) };
|
||||
|
||||
if sigsetsize != size_of::<SigSet>() {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
|
||||
let sighow = SigHow::try_from(how)?;
|
||||
|
||||
let mut new_set = SigSet::default();
|
||||
if let Some(nset) = nset {
|
||||
let reader = UserBufferReader::new(
|
||||
VirtAddr::new(nset).as_ptr::<u64>(),
|
||||
core::mem::size_of::<u64>(),
|
||||
true,
|
||||
)?;
|
||||
|
||||
let nset = reader.read_one_from_user::<u64>(0)?;
|
||||
new_set = SigSet::from_bits_truncate(*nset);
|
||||
// debug!("Get Newset: {}", &new_set.bits());
|
||||
let to_remove: SigSet =
|
||||
<Signal as Into<SigSet>>::into(Signal::SIGKILL) | Signal::SIGSTOP.into();
|
||||
new_set.remove(to_remove);
|
||||
}
|
||||
|
||||
let oldset_to_return = set_sigprocmask(sighow, new_set)?;
|
||||
if let Some(oldset) = oset {
|
||||
// debug!("Get Oldset to return: {}", &oldset_to_return.bits());
|
||||
let mut writer = UserBufferWriter::new(
|
||||
VirtAddr::new(oldset).as_ptr::<u64>(),
|
||||
core::mem::size_of::<u64>(),
|
||||
true,
|
||||
)?;
|
||||
writer.copy_one_to_user::<u64>(&oldset_to_return.bits(), 0)?;
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn restart_syscall() -> Result<usize, SystemError> {
|
||||
let restart_block = ProcessManager::current_pcb().restart_block().take();
|
||||
if let Some(mut restart_block) = restart_block {
|
||||
return restart_block.restart_fn.call(&mut restart_block.data);
|
||||
} else {
|
||||
// 不应该走到这里,因此kill掉当前进程及同组的进程
|
||||
let pid = Pid::new(0);
|
||||
let sig = Signal::SIGKILL;
|
||||
let mut info = SigInfo::new(sig, 0, SigCode::Kernel, SigType::Kill(pid));
|
||||
|
||||
sig.send_signal_info(Some(&mut info), pid)
|
||||
.expect("Failed to kill ");
|
||||
return Ok(0);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn rt_sigpending(user_sigset_ptr: usize, sigsetsize: usize) -> Result<usize, SystemError> {
|
||||
if sigsetsize != size_of::<SigSet>() {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let mut user_buffer_writer =
|
||||
UserBufferWriter::new(user_sigset_ptr as *mut SigSet, size_of::<SigSet>(), true)?;
|
||||
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let siginfo_guard = pcb.sig_info_irqsave();
|
||||
let pending_set = siginfo_guard.sig_pending().signal();
|
||||
let shared_pending_set = siginfo_guard.sig_shared_pending().signal();
|
||||
let blocked_set = *siginfo_guard.sig_blocked();
|
||||
drop(siginfo_guard);
|
||||
|
||||
let mut result = pending_set.union(shared_pending_set);
|
||||
result = result.difference(blocked_set);
|
||||
|
||||
user_buffer_writer.copy_one_to_user(&result, 0)?;
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
}
|
13
kernel/src/ipc/syscall/mod.rs
Normal file
13
kernel/src/ipc/syscall/mod.rs
Normal file
@ -0,0 +1,13 @@
|
||||
pub mod sys_kill;
|
||||
pub mod sys_pipe2;
|
||||
mod sys_restart;
|
||||
mod sys_rt_sigprocmask;
|
||||
mod sys_shmat;
|
||||
mod sys_shmctl;
|
||||
mod sys_shmdt;
|
||||
mod sys_shmget;
|
||||
mod sys_sigaction;
|
||||
mod sys_sigpending;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub mod sys_pipe;
|
90
kernel/src/ipc/syscall/sys_kill.rs
Normal file
90
kernel/src/ipc/syscall/sys_kill.rs
Normal file
@ -0,0 +1,90 @@
|
||||
use alloc::string::ToString;
|
||||
use alloc::vec::Vec;
|
||||
use core::ffi::c_int;
|
||||
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::syscall::table::Syscall;
|
||||
use crate::{
|
||||
arch::{ipc::signal::Signal, syscall::nr::SYS_KILL},
|
||||
process::{process_group::Pgid, Pid, ProcessManager},
|
||||
};
|
||||
use log::warn;
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::ipc::kill::{kill_all, kill_process, kill_process_group};
|
||||
|
||||
/// ### pid转换器,将输入的id转换成对应的pid或pgid
|
||||
/// - 如果id < -1,则为pgid
|
||||
/// - 如果id == -1,则为所有进程
|
||||
/// - 如果id == 0,则为当前进程组
|
||||
/// - 如果id > 0,则为pid
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum PidConverter {
|
||||
All,
|
||||
Pid(Pid),
|
||||
Pgid(Pgid),
|
||||
}
|
||||
|
||||
impl PidConverter {
|
||||
/// ### 为 `wait` 和 `kill` 调用使用
|
||||
pub fn from_id(id: i32) -> Self {
|
||||
if id < -1 {
|
||||
PidConverter::Pgid(Pgid::from(-id as usize))
|
||||
} else if id == -1 {
|
||||
PidConverter::All
|
||||
} else if id == 0 {
|
||||
let pgid = ProcessManager::current_pcb().pgid();
|
||||
PidConverter::Pgid(pgid)
|
||||
} else {
|
||||
PidConverter::Pid(Pid::from(id as usize))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SysKillHandle;
|
||||
|
||||
impl SysKillHandle {
|
||||
#[inline(always)]
|
||||
fn pid(args: &[usize]) -> i32 {
|
||||
// 第一个参数是id
|
||||
args[0] as i32
|
||||
}
|
||||
#[inline(always)]
|
||||
fn sig(args: &[usize]) -> c_int {
|
||||
// 第二个参数是信号值
|
||||
args[1] as c_int
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysKillHandle {
|
||||
fn num_args(&self) -> usize {
|
||||
2
|
||||
}
|
||||
fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
|
||||
let id = Self::pid(args);
|
||||
let sig_c_int = Self::sig(args);
|
||||
|
||||
let converter = PidConverter::from_id(id);
|
||||
let sig = Signal::from(sig_c_int);
|
||||
if sig == Signal::INVALID {
|
||||
warn!("Not a valid signal number");
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
match converter {
|
||||
PidConverter::Pid(pid) => kill_process(pid, sig),
|
||||
PidConverter::Pgid(pgid) => kill_process_group(pgid, sig),
|
||||
PidConverter::All => kill_all(sig),
|
||||
}
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![
|
||||
FormattedSyscallParam::new("pid", Self::pid(args).to_string()),
|
||||
FormattedSyscallParam::new("sig", Self::sig(args).to_string()),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// 注册系统调用
|
||||
syscall_table_macros::declare_syscall!(SYS_KILL, SysKillHandle);
|
44
kernel/src/ipc/syscall/sys_pipe.rs
Normal file
44
kernel/src/ipc/syscall/sys_pipe.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use super::sys_pipe2::do_kernel_pipe2;
|
||||
use crate::arch::syscall::nr::SYS_PIPE;
|
||||
use crate::{
|
||||
filesystem::vfs::file::FileMode,
|
||||
syscall::table::{FormattedSyscallParam, Syscall},
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
use core::ffi::c_int;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysPipeHandle;
|
||||
|
||||
impl SysPipeHandle {
|
||||
#[inline(always)]
|
||||
fn pipefd(args: &[usize]) -> *mut i32 {
|
||||
// 第一个参数是fd指针
|
||||
args[0] as *mut c_int
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysPipeHandle {
|
||||
fn num_args(&self) -> usize {
|
||||
1 // pipefd
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
|
||||
let pipefd = Self::pipefd(args);
|
||||
if pipefd.is_null() {
|
||||
return Err(SystemError::EFAULT);
|
||||
} else {
|
||||
do_kernel_pipe2(pipefd, FileMode::empty())
|
||||
}
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
let fd_ptr = Self::pipefd(args);
|
||||
vec![FormattedSyscallParam::new(
|
||||
"fd_ptr",
|
||||
format!("{}", fd_ptr as usize),
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_PIPE, SysPipeHandle);
|
102
kernel/src/ipc/syscall/sys_pipe2.rs
Normal file
102
kernel/src/ipc/syscall/sys_pipe2.rs
Normal file
@ -0,0 +1,102 @@
|
||||
use crate::{
|
||||
arch::syscall::nr::SYS_PIPE2,
|
||||
filesystem::vfs::{
|
||||
file::{File, FileMode},
|
||||
FilePrivateData,
|
||||
},
|
||||
ipc::pipe::{LockedPipeInode, PipeFsPrivateData},
|
||||
libs::spinlock::SpinLock,
|
||||
process::ProcessManager,
|
||||
syscall::{
|
||||
table::{FormattedSyscallParam, Syscall},
|
||||
user_access::UserBufferWriter,
|
||||
},
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
use core::ffi::c_int;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysPipe2Handle;
|
||||
|
||||
// Extracted core logic for pipe2
|
||||
// pub(super) makes it visible to other modules in kernel/src/ipc/syscall/
|
||||
pub(super) fn do_kernel_pipe2(fd: *mut i32, flags: FileMode) -> Result<usize, SystemError> {
|
||||
if !flags
|
||||
.difference(FileMode::O_CLOEXEC | FileMode::O_NONBLOCK | FileMode::O_DIRECT)
|
||||
.is_empty()
|
||||
{
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let mut user_buffer = UserBufferWriter::new(fd, core::mem::size_of::<[c_int; 2]>(), true)?;
|
||||
let fd = user_buffer.buffer::<i32>(0)?;
|
||||
let pipe_ptr = LockedPipeInode::new();
|
||||
|
||||
let mut read_file = File::new(
|
||||
pipe_ptr.clone(),
|
||||
FileMode::O_RDONLY | (flags & FileMode::O_NONBLOCK),
|
||||
)?;
|
||||
read_file.private_data = SpinLock::new(FilePrivateData::Pipefs(PipeFsPrivateData::new(
|
||||
FileMode::O_RDONLY,
|
||||
)));
|
||||
|
||||
let mut write_file = File::new(
|
||||
pipe_ptr.clone(),
|
||||
FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)),
|
||||
)?;
|
||||
write_file.private_data = SpinLock::new(FilePrivateData::Pipefs(PipeFsPrivateData::new(
|
||||
FileMode::O_WRONLY | (flags & (FileMode::O_NONBLOCK | FileMode::O_DIRECT)),
|
||||
)));
|
||||
|
||||
if flags.contains(FileMode::O_CLOEXEC) {
|
||||
read_file.set_close_on_exec(true);
|
||||
write_file.set_close_on_exec(true);
|
||||
}
|
||||
let fd_table_ptr = ProcessManager::current_pcb().fd_table();
|
||||
let mut fd_table_guard = fd_table_ptr.write();
|
||||
let read_fd = fd_table_guard.alloc_fd(read_file, None)?;
|
||||
let write_fd = fd_table_guard.alloc_fd(write_file, None)?;
|
||||
|
||||
drop(fd_table_guard);
|
||||
|
||||
fd[0] = read_fd;
|
||||
fd[1] = write_fd;
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
impl SysPipe2Handle {
|
||||
#[inline(always)]
|
||||
fn pipefd(args: &[usize]) -> *mut i32 {
|
||||
args[0] as *mut c_int
|
||||
}
|
||||
#[inline(always)]
|
||||
fn flags(args: &[usize]) -> FileMode {
|
||||
FileMode::from_bits_truncate(args[1] as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysPipe2Handle {
|
||||
fn num_args(&self) -> usize {
|
||||
2 // fd_ptr, flags
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
|
||||
let fd_ptr = Self::pipefd(args);
|
||||
if fd_ptr.is_null() {
|
||||
return Err(SystemError::EFAULT);
|
||||
} else {
|
||||
let flags = FileMode::from_bits_truncate(args[1] as u32);
|
||||
do_kernel_pipe2(fd_ptr, flags)
|
||||
}
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
let fd_ptr = Self::pipefd(args);
|
||||
vec![
|
||||
FormattedSyscallParam::new("fd_ptr", format!("{}", fd_ptr as usize)), // Format pointer as hex
|
||||
FormattedSyscallParam::new("flags", format!("{}", Self::flags(args).bits())),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_PIPE2, SysPipe2Handle);
|
49
kernel/src/ipc/syscall/sys_restart.rs
Normal file
49
kernel/src/ipc/syscall/sys_restart.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use super::super::signal_types::{SigInfo, SigType};
|
||||
use crate::{
|
||||
alloc::vec::Vec,
|
||||
arch::ipc::signal::{SigCode, Signal},
|
||||
arch::syscall::nr::SYS_RESTART_SYSCALL,
|
||||
process::{Pid, ProcessManager},
|
||||
syscall::table::{FormattedSyscallParam, Syscall},
|
||||
};
|
||||
use syscall_table_macros::declare_syscall;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysRestartHandle;
|
||||
|
||||
/// # SYS_RESTART_SYSCALL 系统调用函数,用于重启被信号中断的系统调用
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 根据被重启的系统调用决定
|
||||
pub(super) fn do_kernel_restart_syscall() -> Result<usize, SystemError> {
|
||||
let restart_block = ProcessManager::current_pcb().restart_block().take();
|
||||
if let Some(mut restart_block) = restart_block {
|
||||
return restart_block.restart_fn.call(&mut restart_block.data);
|
||||
} else {
|
||||
// 不应该走到这里,因此kill掉当前进程及同组的进程
|
||||
let pid = Pid::new(0);
|
||||
let sig = Signal::SIGKILL;
|
||||
let mut info = SigInfo::new(sig, 0, SigCode::Kernel, SigType::Kill(pid));
|
||||
|
||||
sig.send_signal_info(Some(&mut info), pid)
|
||||
.expect("Failed to kill ");
|
||||
return Ok(0);
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysRestartHandle {
|
||||
fn num_args(&self) -> usize {
|
||||
0 // restart_syscall 通常没有参数
|
||||
}
|
||||
|
||||
fn entry_format(&self, _args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
Vec::new() // 没有参数,返回空Vec
|
||||
}
|
||||
|
||||
fn handle(&self, _args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
|
||||
do_kernel_restart_syscall()
|
||||
}
|
||||
}
|
||||
|
||||
declare_syscall!(SYS_RESTART_SYSCALL, SysRestartHandle);
|
135
kernel/src/ipc/syscall/sys_rt_sigprocmask.rs
Normal file
135
kernel/src/ipc/syscall/sys_rt_sigprocmask.rs
Normal file
@ -0,0 +1,135 @@
|
||||
use crate::alloc::vec::Vec;
|
||||
use crate::{
|
||||
arch::ipc::signal::{SigSet, Signal},
|
||||
arch::syscall::nr::SYS_RT_SIGPROCMASK,
|
||||
ipc::signal::{set_sigprocmask, SigHow},
|
||||
mm::VirtAddr,
|
||||
syscall::{
|
||||
table::{FormattedSyscallParam, Syscall},
|
||||
user_access::{UserBufferReader, UserBufferWriter},
|
||||
},
|
||||
};
|
||||
use core::mem::size_of;
|
||||
use syscall_table_macros::declare_syscall;
|
||||
use system_error::SystemError; // 添加 Vec
|
||||
|
||||
pub struct SysRtSigprocmaskHandle;
|
||||
|
||||
/// # SYS_SIGPROCMASK系统调用函数,用于设置或查询当前进程的信号屏蔽字
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `how`: 指示如何修改信号屏蔽字
|
||||
/// - `nset`: 新的信号屏蔽字
|
||||
/// - `oset`: 旧的信号屏蔽字的指针,由于可以是NULL,所以用Option包装
|
||||
/// - `sigsetsize`: 信号集的大小
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:0
|
||||
/// 失败:错误码
|
||||
///
|
||||
/// ## 说明
|
||||
/// 根据 https://man7.org/linux/man-pages/man2/sigprocmask.2.html ,传进来的oldset和newset都是指针类型,这里选择传入usize然后转换为u64的指针类型
|
||||
pub(super) fn do_kernel_rt_sigprocmask(
|
||||
how: i32,
|
||||
newset: usize,
|
||||
oldset: usize,
|
||||
sigsetsize: usize,
|
||||
) -> Result<usize, SystemError> {
|
||||
// 对应oset传进来一个NULL的情况
|
||||
let oset = if oldset == 0 { None } else { Some(oldset) };
|
||||
let nset = if newset == 0 { None } else { Some(newset) };
|
||||
|
||||
if sigsetsize != size_of::<SigSet>() {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
|
||||
let sighow = SigHow::try_from(how)?;
|
||||
|
||||
let mut new_set = SigSet::default();
|
||||
if let Some(nset) = nset {
|
||||
let reader = UserBufferReader::new(
|
||||
VirtAddr::new(nset).as_ptr::<u64>(),
|
||||
core::mem::size_of::<u64>(),
|
||||
true,
|
||||
)?;
|
||||
|
||||
let nset = reader.read_one_from_user::<u64>(0)?;
|
||||
new_set = SigSet::from_bits_truncate(*nset);
|
||||
// debug!("Get Newset: {}", &new_set.bits());
|
||||
let to_remove: SigSet =
|
||||
<Signal as Into<SigSet>>::into(Signal::SIGKILL) | Signal::SIGSTOP.into();
|
||||
new_set.remove(to_remove);
|
||||
}
|
||||
|
||||
let oldset_to_return = set_sigprocmask(sighow, new_set)?;
|
||||
if let Some(oldset) = oset {
|
||||
// debug!("Get Oldset to return: {}", &oldset_to_return.bits());
|
||||
let mut writer = UserBufferWriter::new(
|
||||
VirtAddr::new(oldset).as_ptr::<u64>(),
|
||||
core::mem::size_of::<u64>(),
|
||||
true,
|
||||
)?;
|
||||
writer.copy_one_to_user::<u64>(&oldset_to_return.bits(), 0)?;
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
impl SysRtSigprocmaskHandle {
|
||||
#[inline(always)]
|
||||
fn how(args: &[usize]) -> i32 {
|
||||
// 第一个参数是 how
|
||||
args[0] as i32
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn nset(args: &[usize]) -> usize {
|
||||
// 第二个参数是新信号集的指针
|
||||
args[1]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn oset(args: &[usize]) -> usize {
|
||||
// 第三个参数是旧信号集的指针
|
||||
args[2]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn sigsetsize(args: &[usize]) -> usize {
|
||||
// 第四个参数是 sigset_t 的大小
|
||||
args[3]
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysRtSigprocmaskHandle {
|
||||
fn num_args(&self) -> usize {
|
||||
4
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
let how = Self::how(args);
|
||||
let nset_ptr = Self::nset(args);
|
||||
let oset_ptr = Self::oset(args);
|
||||
let sigsetsize = Self::sigsetsize(args);
|
||||
|
||||
vec![
|
||||
FormattedSyscallParam::new("how", format!("{:#x}", how)),
|
||||
FormattedSyscallParam::new("nset", format!("{:#x}", nset_ptr)),
|
||||
FormattedSyscallParam::new("oset", format!("{:#x}", oset_ptr)),
|
||||
FormattedSyscallParam::new("sigsetsize", format!("{}", sigsetsize)),
|
||||
]
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
|
||||
let how = Self::how(args);
|
||||
let nset = Self::nset(args);
|
||||
let oset = Self::oset(args);
|
||||
let sigsetsize = Self::sigsetsize(args);
|
||||
|
||||
do_kernel_rt_sigprocmask(how, nset, oset, sigsetsize)
|
||||
}
|
||||
}
|
||||
|
||||
declare_syscall!(SYS_RT_SIGPROCMASK, SysRtSigprocmaskHandle);
|
179
kernel/src/ipc/syscall/sys_shmat.rs
Normal file
179
kernel/src/ipc/syscall/sys_shmat.rs
Normal file
@ -0,0 +1,179 @@
|
||||
use crate::alloc::vec::Vec;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::{
|
||||
arch::syscall::nr::SYS_SHMAT,
|
||||
arch::MMArch,
|
||||
ipc::shm::{shm_manager_lock, ShmFlags, ShmId},
|
||||
libs::align::page_align_up,
|
||||
mm::{
|
||||
allocator::page_frame::{PageFrameCount, PhysPageFrame, VirtPageFrame},
|
||||
page::{page_manager_lock_irqsave, EntryFlags, PageFlushAll},
|
||||
syscall::ProtFlags,
|
||||
ucontext::{AddressSpace, VMA},
|
||||
VirtAddr, VmFlags,
|
||||
},
|
||||
syscall::{table::Syscall, user_access::UserBufferReader},
|
||||
};
|
||||
use syscall_table_macros::declare_syscall;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysShmatHandle;
|
||||
|
||||
/// # SYS_SHMAT系统调用函数,用于连接共享内存段
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `id`: 共享内存id
|
||||
/// - `vaddr`: 连接共享内存的进程虚拟内存区域起始地址
|
||||
/// - `shmflg`: 共享内存标志
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:映射到共享内存的虚拟内存区域起始地址
|
||||
/// 失败:错误码
|
||||
pub(super) fn do_kernel_shmat(
|
||||
id: ShmId,
|
||||
vaddr: VirtAddr,
|
||||
shmflg: ShmFlags,
|
||||
) -> Result<usize, SystemError> {
|
||||
let mut shm_manager_guard = shm_manager_lock();
|
||||
let current_address_space = AddressSpace::current()?;
|
||||
let mut address_write_guard = current_address_space.write();
|
||||
|
||||
let kernel_shm = shm_manager_guard.get_mut(&id).ok_or(SystemError::EINVAL)?;
|
||||
let size = page_align_up(kernel_shm.size());
|
||||
let mut phys = PhysPageFrame::new(kernel_shm.start_paddr());
|
||||
let count = PageFrameCount::from_bytes(size).unwrap();
|
||||
let r = match vaddr.data() {
|
||||
// 找到空闲区域并映射到共享内存
|
||||
0 => {
|
||||
// 找到空闲区域
|
||||
let region = address_write_guard
|
||||
.mappings
|
||||
.find_free(vaddr, size)
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
let vm_flags = VmFlags::from(shmflg);
|
||||
let destination = VirtPageFrame::new(region.start());
|
||||
let page_flags: EntryFlags<MMArch> =
|
||||
EntryFlags::from_prot_flags(ProtFlags::from(vm_flags), true);
|
||||
let flusher: PageFlushAll<MMArch> = PageFlushAll::new();
|
||||
|
||||
// 将共享内存映射到对应虚拟区域
|
||||
let vma = VMA::physmap(
|
||||
phys,
|
||||
destination,
|
||||
count,
|
||||
vm_flags,
|
||||
page_flags,
|
||||
&mut address_write_guard.user_mapper.utable,
|
||||
flusher,
|
||||
)?;
|
||||
|
||||
// 将VMA加入到当前进程的VMA列表中
|
||||
address_write_guard.mappings.insert_vma(vma);
|
||||
|
||||
region.start().data()
|
||||
}
|
||||
// 指定虚拟地址
|
||||
_ => {
|
||||
// 获取对应vma
|
||||
let vma = address_write_guard
|
||||
.mappings
|
||||
.contains(vaddr)
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
if vma.lock_irqsave().region().start() != vaddr {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
// 验证用户虚拟内存区域是否有效
|
||||
let _ = UserBufferReader::new(vaddr.data() as *const u8, size, true)?;
|
||||
|
||||
// 必须在取消映射前获取到EntryFlags
|
||||
let page_flags = address_write_guard
|
||||
.user_mapper
|
||||
.utable
|
||||
.translate(vaddr)
|
||||
.ok_or(SystemError::EINVAL)?
|
||||
.1;
|
||||
|
||||
// 取消原映射
|
||||
let flusher: PageFlushAll<MMArch> = PageFlushAll::new();
|
||||
vma.unmap(&mut address_write_guard.user_mapper.utable, flusher);
|
||||
|
||||
// 将该虚拟内存区域映射到共享内存区域
|
||||
let mut page_manager_guard = page_manager_lock_irqsave();
|
||||
let mut virt = VirtPageFrame::new(vaddr);
|
||||
for _ in 0..count.data() {
|
||||
let r = unsafe {
|
||||
address_write_guard.user_mapper.utable.map_phys(
|
||||
virt.virt_address(),
|
||||
phys.phys_address(),
|
||||
page_flags,
|
||||
)
|
||||
}
|
||||
.expect("Failed to map zero, may be OOM error");
|
||||
r.flush();
|
||||
|
||||
// 将vma加入到对应Page的anon_vma
|
||||
page_manager_guard
|
||||
.get_unwrap(&phys.phys_address())
|
||||
.write_irqsave()
|
||||
.insert_vma(vma.clone());
|
||||
|
||||
phys = phys.next();
|
||||
virt = virt.next();
|
||||
}
|
||||
|
||||
// 更新vma的映射状态
|
||||
vma.lock_irqsave().set_mapped(true);
|
||||
|
||||
vaddr.data()
|
||||
}
|
||||
};
|
||||
|
||||
// 更新最后一次连接时间
|
||||
kernel_shm.update_atim();
|
||||
|
||||
// 映射计数增加
|
||||
kernel_shm.increase_count();
|
||||
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
impl SysShmatHandle {
|
||||
#[inline(always)]
|
||||
fn id(args: &[usize]) -> ShmId {
|
||||
ShmId::new(args[0]) // 更正 ShmIT 为 ShmId
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn vaddr(args: &[usize]) -> VirtAddr {
|
||||
VirtAddr::new(args[1])
|
||||
}
|
||||
#[inline(always)]
|
||||
fn shmflg(args: &[usize]) -> ShmFlags {
|
||||
ShmFlags::from_bits_truncate(args[2] as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysShmatHandle {
|
||||
fn num_args(&self) -> usize {
|
||||
3
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![
|
||||
FormattedSyscallParam::new("id", format!("{}", Self::id(args).data())),
|
||||
FormattedSyscallParam::new("vaddr", format!("{}", Self::vaddr(args).data())),
|
||||
FormattedSyscallParam::new("shmflg", format!("{}", Self::shmflg(args).bits())),
|
||||
]
|
||||
}
|
||||
fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
|
||||
let id = Self::id(args);
|
||||
let vaddr = Self::vaddr(args);
|
||||
let shmflg = Self::shmflg(args);
|
||||
do_kernel_shmat(id, vaddr, shmflg)
|
||||
}
|
||||
}
|
||||
|
||||
declare_syscall!(SYS_SHMAT, SysShmatHandle);
|
92
kernel/src/ipc/syscall/sys_shmctl.rs
Normal file
92
kernel/src/ipc/syscall/sys_shmctl.rs
Normal file
@ -0,0 +1,92 @@
|
||||
use crate::alloc::vec::Vec;
|
||||
use crate::{
|
||||
arch::syscall::nr::SYS_SHMCTL,
|
||||
ipc::shm::{shm_manager_lock, ShmCtlCmd, ShmId},
|
||||
syscall::table::{FormattedSyscallParam, Syscall},
|
||||
};
|
||||
use syscall_table_macros::declare_syscall;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysShmctlHandle;
|
||||
|
||||
/// # SYS_SHMCTL系统调用函数,用于管理共享内存段
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `id`: 共享内存id
|
||||
/// - `cmd`: 操作码
|
||||
/// - `user_buf`: 用户缓冲区
|
||||
/// - `from_user`: buf_vaddr是否来自用户地址空间
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:0
|
||||
/// 失败:错误码
|
||||
pub(super) fn do_kernel_shmctl(
|
||||
id: ShmId,
|
||||
cmd: ShmCtlCmd,
|
||||
user_buf: *const u8,
|
||||
from_user: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
let mut shm_manager_guard = shm_manager_lock();
|
||||
|
||||
match cmd {
|
||||
// 查看共享内存元信息
|
||||
ShmCtlCmd::IpcInfo => shm_manager_guard.ipc_info(user_buf, from_user),
|
||||
// 查看共享内存使用信息
|
||||
ShmCtlCmd::ShmInfo => shm_manager_guard.shm_info(user_buf, from_user),
|
||||
// 查看id对应的共享内存信息
|
||||
ShmCtlCmd::ShmStat | ShmCtlCmd::ShmtStatAny | ShmCtlCmd::IpcStat => {
|
||||
shm_manager_guard.shm_stat(id, cmd, user_buf, from_user)
|
||||
}
|
||||
// 设置KernIpcPerm
|
||||
ShmCtlCmd::IpcSet => shm_manager_guard.ipc_set(id, user_buf, from_user),
|
||||
// 将共享内存段设置为可回收状态
|
||||
ShmCtlCmd::IpcRmid => shm_manager_guard.ipc_rmid(id),
|
||||
// 锁住共享内存段,不允许内存置换
|
||||
ShmCtlCmd::ShmLock => shm_manager_guard.shm_lock(id),
|
||||
// 解锁共享内存段,允许内存置换
|
||||
ShmCtlCmd::ShmUnlock => shm_manager_guard.shm_unlock(id),
|
||||
// 无效操作码
|
||||
ShmCtlCmd::Default => Err(SystemError::EINVAL),
|
||||
}
|
||||
}
|
||||
|
||||
impl SysShmctlHandle {
|
||||
#[inline(always)]
|
||||
fn id(args: &[usize]) -> ShmId {
|
||||
ShmId::new(args[0]) // Assuming ShmId::new takes usize or can infer from args[0]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn cmd(args: &[usize]) -> ShmCtlCmd {
|
||||
ShmCtlCmd::from(args[1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn user_buf(args: &[usize]) -> *const u8 {
|
||||
args[2] as *const u8 // Assuming args[2] is a pointer to user buffer
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysShmctlHandle {
|
||||
fn num_args(&self) -> usize {
|
||||
3
|
||||
}
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![
|
||||
FormattedSyscallParam::new("shmid", format!("{}", Self::id(args).data())),
|
||||
FormattedSyscallParam::new("cmd", format!("{}", Self::cmd(args))),
|
||||
FormattedSyscallParam::new("buf", format!("{:#x}", Self::user_buf(args) as usize)),
|
||||
]
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], from_user: bool) -> Result<usize, SystemError> {
|
||||
let id = Self::id(args);
|
||||
let cmd = Self::cmd(args);
|
||||
let user_buf = Self::user_buf(args);
|
||||
do_kernel_shmctl(id, cmd, user_buf, from_user)
|
||||
}
|
||||
}
|
||||
|
||||
declare_syscall!(SYS_SHMCTL, SysShmctlHandle);
|
67
kernel/src/ipc/syscall/sys_shmdt.rs
Normal file
67
kernel/src/ipc/syscall/sys_shmdt.rs
Normal file
@ -0,0 +1,67 @@
|
||||
use crate::mm::page::PageFlushAll;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::{
|
||||
arch::syscall::nr::SYS_SHMDT,
|
||||
arch::MMArch,
|
||||
mm::{ucontext::AddressSpace, VirtAddr},
|
||||
syscall::table::Syscall,
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
use syscall_table_macros::declare_syscall;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysShmdtHandle;
|
||||
|
||||
impl SysShmdtHandle {
|
||||
#[inline(always)]
|
||||
fn vaddr(args: &[usize]) -> VirtAddr {
|
||||
VirtAddr::new(args[0])
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysShmdtHandle {
|
||||
fn num_args(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![FormattedSyscallParam::new(
|
||||
"vaddr",
|
||||
format!("{}", Self::vaddr(args).data()),
|
||||
)]
|
||||
}
|
||||
/// # SYS_SHMDT系统调用函数,用于取消对共享内存的连接
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `vaddr`: 需要取消映射的虚拟内存区域起始地址
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:0
|
||||
/// 失败:错误码
|
||||
fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
|
||||
let vaddr = Self::vaddr(args);
|
||||
let current_address_space = AddressSpace::current()?;
|
||||
let mut address_write_guard = current_address_space.write();
|
||||
|
||||
// 获取vma
|
||||
let vma = address_write_guard
|
||||
.mappings
|
||||
.contains(vaddr)
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
|
||||
// 判断vaddr是否为起始地址
|
||||
if vma.lock_irqsave().region().start() != vaddr {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
// 取消映射
|
||||
let flusher: PageFlushAll<MMArch> = PageFlushAll::new();
|
||||
vma.unmap(&mut address_write_guard.user_mapper.utable, flusher);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
}
|
||||
|
||||
declare_syscall!(SYS_SHMDT, SysShmdtHandle);
|
110
kernel/src/ipc/syscall/sys_shmget.rs
Normal file
110
kernel/src/ipc/syscall/sys_shmget.rs
Normal file
@ -0,0 +1,110 @@
|
||||
use crate::alloc::vec::Vec;
|
||||
use crate::syscall::table::FormattedSyscallParam;
|
||||
use crate::{
|
||||
arch::syscall::nr::SYS_SHMGET,
|
||||
ipc::shm::{shm_manager_lock, ShmFlags, ShmKey, IPC_PRIVATE},
|
||||
syscall::table::Syscall,
|
||||
};
|
||||
use log::error;
|
||||
use syscall_table_macros::declare_syscall;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysShmgetHandle;
|
||||
|
||||
/// # SYS_SHMGET系统调用函数,用于获取共享内存
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `key`: 共享内存键值
|
||||
/// - `size`: 共享内存大小(bytes)
|
||||
/// - `shmflg`: 共享内存标志
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 成功:共享内存id
|
||||
/// 失败:错误码
|
||||
pub(super) fn do_kernel_shmget(
|
||||
key: ShmKey,
|
||||
size: usize,
|
||||
shmflg: ShmFlags,
|
||||
) -> Result<usize, SystemError> {
|
||||
// 暂不支持巨页
|
||||
if shmflg.contains(ShmFlags::SHM_HUGETLB) {
|
||||
error!("shmget: not support huge page");
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
|
||||
let mut shm_manager_guard = shm_manager_lock();
|
||||
match key {
|
||||
// 创建共享内存段
|
||||
IPC_PRIVATE => shm_manager_guard.add(key, size, shmflg),
|
||||
_ => {
|
||||
// 查找key对应的共享内存段是否存在
|
||||
let id = shm_manager_guard.contains_key(&key);
|
||||
if let Some(id) = id {
|
||||
// 不能重复创建
|
||||
if shmflg.contains(ShmFlags::IPC_CREAT | ShmFlags::IPC_EXCL) {
|
||||
return Err(SystemError::EEXIST);
|
||||
}
|
||||
|
||||
// key值存在,说明有对应共享内存,返回该共享内存id
|
||||
return Ok(id.data());
|
||||
} else {
|
||||
// key不存在且shm_flags不包含IPC_CREAT创建IPC对象标志,则返回错误码
|
||||
if !shmflg.contains(ShmFlags::IPC_CREAT) {
|
||||
return Err(SystemError::ENOENT);
|
||||
}
|
||||
|
||||
// 存在创建IPC对象标志
|
||||
return shm_manager_guard.add(key, size, shmflg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SysShmgetHandle {
|
||||
#[inline(always)]
|
||||
fn key(args: &[usize]) -> ShmKey {
|
||||
// 第一个参数是共享内存的key
|
||||
// In the old code: ShmKey::new(args[0])
|
||||
// ShmKey is likely a type alias for i32 or similar, args[0] is usize
|
||||
ShmKey::new(args[0]) // Assuming ShmKey::new takes i32
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn size(args: &[usize]) -> usize {
|
||||
// 第二个参数是共享内存的大小
|
||||
args[1]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn shmflg(args: &[usize]) -> ShmFlags {
|
||||
// 第三个参数是共享内存的标志
|
||||
// In the old code: ShmFlags::from_bits_truncate(args[2] as u32)
|
||||
ShmFlags::from_bits_truncate(args[2] as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysShmgetHandle {
|
||||
fn num_args(&self) -> usize {
|
||||
3 // key, size, shmflg
|
||||
}
|
||||
|
||||
fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
|
||||
let key = Self::key(args);
|
||||
let size = Self::size(args);
|
||||
let shmflg = Self::shmflg(args);
|
||||
do_kernel_shmget(key, size, shmflg)
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![
|
||||
FormattedSyscallParam::new("key", format!("{}", Self::key(args).data())),
|
||||
// 使用 format! 宏将 usize 类型的 size 转换为 String
|
||||
FormattedSyscallParam::new("size", format!("{}", Self::size(args))),
|
||||
FormattedSyscallParam::new("shmflg", format!("{:#x}", Self::shmflg(args).bits())),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
declare_syscall!(SYS_SHMGET, SysShmgetHandle);
|
191
kernel/src/ipc/syscall/sys_sigaction.rs
Normal file
191
kernel/src/ipc/syscall/sys_sigaction.rs
Normal file
@ -0,0 +1,191 @@
|
||||
use super::super::signal_types::{
|
||||
SaHandlerType, Sigaction, SigactionType, UserSigaction, USER_SIG_DFL, USER_SIG_ERR,
|
||||
USER_SIG_IGN,
|
||||
};
|
||||
use crate::arch::syscall::nr::SYS_RT_SIGACTION;
|
||||
use crate::syscall::table::{FormattedSyscallParam, Syscall};
|
||||
use crate::{
|
||||
arch::ipc::signal::{SigFlags, SigSet, Signal},
|
||||
mm::VirtAddr,
|
||||
process::ProcessManager,
|
||||
syscall::user_access::UserBufferWriter,
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
use core::ffi::{c_int, c_void};
|
||||
use log::error;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysSigactionHandle;
|
||||
|
||||
/// 通用信号注册函数
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `sig` 信号的值
|
||||
/// - `act` 用户空间传入的 Sigaction 指针
|
||||
/// - `old_act` 用户空间传入的用来保存旧 Sigaction 的指针
|
||||
/// - `from_user` 用来标识这个函数调用是否来自用户空间
|
||||
///
|
||||
/// @return int 错误码
|
||||
#[no_mangle]
|
||||
pub(super) fn do_kernel_sigaction(
|
||||
sig: c_int,
|
||||
new_act: usize,
|
||||
old_act: usize,
|
||||
from_user: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
// 请注意:用户态传进来的user_sigaction结构体类型,请注意,这个结构体与内核实际的不一样
|
||||
let act: *mut UserSigaction = new_act as *mut UserSigaction;
|
||||
let old_act = old_act as *mut UserSigaction;
|
||||
let mut new_ka: Sigaction = Default::default();
|
||||
let mut old_sigaction: Sigaction = Default::default();
|
||||
// 如果传入的,新的sigaction不为空
|
||||
if !act.is_null() {
|
||||
// 如果参数的范围不在用户空间,则返回错误
|
||||
let r = UserBufferWriter::new(act, core::mem::size_of::<Sigaction>(), from_user);
|
||||
if r.is_err() {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
let mask: SigSet = unsafe { (*act).mask };
|
||||
let input_sighandler = unsafe { (*act).handler as u64 };
|
||||
match input_sighandler {
|
||||
USER_SIG_DFL => {
|
||||
new_ka = Sigaction::DEFAULT_SIGACTION;
|
||||
*new_ka.flags_mut() = unsafe { (*act).flags };
|
||||
new_ka.set_restorer(None);
|
||||
}
|
||||
|
||||
USER_SIG_IGN => {
|
||||
new_ka = Sigaction::DEFAULT_SIGACTION_IGNORE;
|
||||
*new_ka.flags_mut() = unsafe { (*act).flags };
|
||||
|
||||
new_ka.set_restorer(None);
|
||||
}
|
||||
_ => {
|
||||
// 从用户空间获得sigaction结构体
|
||||
// TODO mask是default还是用户空间传入
|
||||
new_ka = Sigaction::new(
|
||||
SigactionType::SaHandler(SaHandlerType::Customized(unsafe {
|
||||
VirtAddr::new((*act).handler as usize)
|
||||
})),
|
||||
unsafe { (*act).flags },
|
||||
SigSet::default(),
|
||||
unsafe { Some(VirtAddr::new((*act).restorer as usize)) },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 如果为空,赋默认值?
|
||||
// debug!("new_ka={:?}", new_ka);
|
||||
// 如果用户手动给了sa_restorer,那么就置位SA_FLAG_RESTORER,否则报错。(用户必须手动指定restorer)
|
||||
if new_ka.restorer().is_some() {
|
||||
new_ka.flags_mut().insert(SigFlags::SA_RESTORER);
|
||||
} else if new_ka.action().is_customized() {
|
||||
error!(
|
||||
"pid:{:?}: in sys_sigaction: User must manually sprcify a sa_restorer for signal {}.",
|
||||
ProcessManager::current_pcb().pid(),
|
||||
sig
|
||||
);
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
*new_ka.mask_mut() = mask;
|
||||
}
|
||||
|
||||
let sig = Signal::from(sig);
|
||||
// 如果给出的信号值不合法
|
||||
if sig == Signal::INVALID {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let retval = super::super::signal::do_sigaction(
|
||||
sig,
|
||||
if act.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&mut new_ka)
|
||||
},
|
||||
if old_act.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&mut old_sigaction)
|
||||
},
|
||||
);
|
||||
|
||||
//
|
||||
if (retval == Ok(())) && (!old_act.is_null()) {
|
||||
let r = UserBufferWriter::new(old_act, core::mem::size_of::<UserSigaction>(), from_user);
|
||||
if r.is_err() {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
|
||||
let sigaction_handler = match old_sigaction.action() {
|
||||
SigactionType::SaHandler(handler) => {
|
||||
if let SaHandlerType::Customized(hand) = handler {
|
||||
hand
|
||||
} else if handler.is_sig_ignore() {
|
||||
VirtAddr::new(USER_SIG_IGN as usize)
|
||||
} else if handler.is_sig_error() {
|
||||
VirtAddr::new(USER_SIG_ERR as usize)
|
||||
} else {
|
||||
VirtAddr::new(USER_SIG_DFL as usize)
|
||||
}
|
||||
}
|
||||
SigactionType::SaSigaction(_) => {
|
||||
error!("unsupported type: SaSigaction");
|
||||
VirtAddr::new(USER_SIG_DFL as usize)
|
||||
}
|
||||
};
|
||||
|
||||
unsafe {
|
||||
(*old_act).handler = sigaction_handler.data() as *mut c_void;
|
||||
(*old_act).flags = old_sigaction.flags();
|
||||
(*old_act).mask = old_sigaction.mask();
|
||||
if old_sigaction.restorer().is_some() {
|
||||
(*old_act).restorer = old_sigaction.restorer().unwrap().data() as *mut c_void;
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval.map(|_| 0);
|
||||
}
|
||||
|
||||
impl SysSigactionHandle {
|
||||
#[inline(always)]
|
||||
fn sig(args: &[usize]) -> c_int {
|
||||
// 第一个参数是信号值
|
||||
args[0] as c_int
|
||||
}
|
||||
#[inline(always)]
|
||||
fn act(args: &[usize]) -> usize {
|
||||
// 第二个参数是用户空间传入的 Sigaction 指针
|
||||
args[1]
|
||||
}
|
||||
#[inline(always)]
|
||||
fn old_act(args: &[usize]) -> usize {
|
||||
// 第三个参数是用户空间传入的用来保存旧 Sigaction 的指针
|
||||
args[2]
|
||||
}
|
||||
}
|
||||
|
||||
impl Syscall for SysSigactionHandle {
|
||||
fn num_args(&self) -> usize {
|
||||
3
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn handle(&self, args: &[usize], from_user: bool) -> Result<usize, SystemError> {
|
||||
let sig = Self::sig(args);
|
||||
let act = Self::act(args);
|
||||
let old_act = Self::old_act(args);
|
||||
|
||||
do_kernel_sigaction(sig, act, old_act, from_user)
|
||||
}
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![
|
||||
FormattedSyscallParam::new("sig", format!("{}", Self::sig(args))),
|
||||
FormattedSyscallParam::new("act", format!("{:#x}", Self::act(args))),
|
||||
FormattedSyscallParam::new("old_act", format!("{:#x}", Self::old_act(args))),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
syscall_table_macros::declare_syscall!(SYS_RT_SIGACTION, SysSigactionHandle);
|
76
kernel/src/ipc/syscall/sys_sigpending.rs
Normal file
76
kernel/src/ipc/syscall/sys_sigpending.rs
Normal file
@ -0,0 +1,76 @@
|
||||
use crate::{
|
||||
alloc::vec::Vec,
|
||||
arch::ipc::signal::SigSet,
|
||||
arch::syscall::nr::SYS_RT_SIGPENDING,
|
||||
process::ProcessManager,
|
||||
syscall::{
|
||||
table::{FormattedSyscallParam, Syscall},
|
||||
user_access::UserBufferWriter,
|
||||
},
|
||||
};
|
||||
use core::mem::size_of;
|
||||
use syscall_table_macros::declare_syscall;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub struct SysSigpendingHandle;
|
||||
|
||||
#[inline(never)]
|
||||
pub(super) fn do_kernel_rt_sigpending(
|
||||
user_sigset_ptr: usize,
|
||||
sigsetsize: usize,
|
||||
) -> Result<usize, SystemError> {
|
||||
if sigsetsize != size_of::<SigSet>() {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let mut user_buffer_writer =
|
||||
UserBufferWriter::new(user_sigset_ptr as *mut SigSet, size_of::<SigSet>(), true)?;
|
||||
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let siginfo_guard = pcb.sig_info_irqsave();
|
||||
let pending_set = siginfo_guard.sig_pending().signal();
|
||||
let shared_pending_set = siginfo_guard.sig_shared_pending().signal();
|
||||
let blocked_set = *siginfo_guard.sig_blocked();
|
||||
drop(siginfo_guard);
|
||||
|
||||
let mut result = pending_set.union(shared_pending_set);
|
||||
result = result.difference(blocked_set);
|
||||
|
||||
user_buffer_writer.copy_one_to_user(&result, 0)?;
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
impl Syscall for SysSigpendingHandle {
|
||||
fn num_args(&self) -> usize {
|
||||
2 // sigpending(sigset_t *set)
|
||||
}
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
vec![
|
||||
FormattedSyscallParam::new("user_sigset_ptr", format!("{}", args[0])),
|
||||
FormattedSyscallParam::new("sigsetsize", format!("{}", args[1])),
|
||||
]
|
||||
}
|
||||
fn handle(&self, args: &[usize], _from_user: bool) -> Result<usize, SystemError> {
|
||||
let user_sigset = SysSigpendingHandle::user_sigset_ptr(args);
|
||||
let size = SysSigpendingHandle::sigsetsize(args);
|
||||
|
||||
do_kernel_rt_sigpending(user_sigset, size)
|
||||
}
|
||||
}
|
||||
|
||||
impl SysSigpendingHandle {
|
||||
#[inline(always)]
|
||||
fn user_sigset_ptr(args: &[usize]) -> usize {
|
||||
// 第一个参数是用户空间信号集的指针
|
||||
args[0]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn sigsetsize(args: &[usize]) -> usize {
|
||||
// 第二个参数是 sigset_t 的大小
|
||||
args[1]
|
||||
}
|
||||
}
|
||||
|
||||
declare_syscall!(SYS_RT_SIGPENDING, SysSigpendingHandle);
|
@ -4,7 +4,7 @@ use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::ipc::signal::{SigChildCode, Signal},
|
||||
ipc::syscall::PidConverter,
|
||||
ipc::syscall::sys_kill::PidConverter,
|
||||
sched::{schedule, SchedMode},
|
||||
syscall::user_access::UserBufferWriter,
|
||||
time::{sleep::nanosleep, Duration},
|
||||
|
@ -67,7 +67,7 @@ use crate::{
|
||||
cpu::{AtomicProcessorId, ProcessorId},
|
||||
kick_cpu,
|
||||
},
|
||||
syscall::{user_access::clear_user, Syscall},
|
||||
syscall::user_access::clear_user,
|
||||
};
|
||||
use timer::AlarmTimer;
|
||||
|
||||
@ -386,7 +386,7 @@ impl ProcessManager {
|
||||
return;
|
||||
}
|
||||
let parent_pcb = r.unwrap();
|
||||
let r = Syscall::kill_process(parent_pcb.pid(), Signal::SIGCHLD);
|
||||
let r = crate::ipc::kill::kill_process(parent_pcb.pid(), Signal::SIGCHLD);
|
||||
if r.is_err() {
|
||||
warn!(
|
||||
"failed to send kill signal to {:?}'s parent pcb {:?}",
|
||||
|
@ -6,7 +6,6 @@ use core::{
|
||||
use crate::{
|
||||
arch::syscall::nr::*,
|
||||
filesystem::vfs::syscall::PosixStatfs,
|
||||
ipc::shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey},
|
||||
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
||||
mm::{page::PAGE_4K_SIZE, syscall::MremapFlags},
|
||||
net::syscall::MsgHdr,
|
||||
@ -29,7 +28,6 @@ use crate::{
|
||||
arch::{interrupt::TrapFrame, MMArch},
|
||||
filesystem::vfs::{
|
||||
fcntl::{AtFlags, FcntlCommand},
|
||||
file::FileMode,
|
||||
syscall::{ModeType, UtimensFlags},
|
||||
MAX_PATHLEN,
|
||||
},
|
||||
@ -314,27 +312,6 @@ impl Syscall {
|
||||
}
|
||||
|
||||
SYS_CLOCK => Self::clock(),
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_PIPE => {
|
||||
let pipefd: *mut i32 = args[0] as *mut c_int;
|
||||
if pipefd.is_null() {
|
||||
Err(SystemError::EFAULT)
|
||||
} else {
|
||||
Self::pipe2(pipefd, FileMode::empty())
|
||||
}
|
||||
}
|
||||
|
||||
SYS_PIPE2 => {
|
||||
let pipefd: *mut i32 = args[0] as *mut c_int;
|
||||
let arg1 = args[1];
|
||||
if pipefd.is_null() {
|
||||
Err(SystemError::EFAULT)
|
||||
} else {
|
||||
let flags = FileMode::from_bits_truncate(arg1 as u32);
|
||||
Self::pipe2(pipefd, flags)
|
||||
}
|
||||
}
|
||||
|
||||
SYS_UNLINKAT => {
|
||||
let dirfd = args[0] as i32;
|
||||
let path = args[1] as *const u8;
|
||||
@ -383,20 +360,6 @@ impl Syscall {
|
||||
let path = args[0] as *const u8;
|
||||
Self::unlink(path)
|
||||
}
|
||||
SYS_KILL => {
|
||||
let pid = args[0] as i32;
|
||||
let sig = args[1] as c_int;
|
||||
// debug!("KILL SYSCALL RECEIVED");
|
||||
Self::kill(pid, sig)
|
||||
}
|
||||
|
||||
SYS_RT_SIGACTION => {
|
||||
let sig = args[0] as c_int;
|
||||
let act = args[1];
|
||||
let old_act = args[2];
|
||||
Self::sigaction(sig, act, old_act, frame.is_from_user())
|
||||
}
|
||||
|
||||
SYS_GETPID => Self::getpid().map(|pid| pid.into()),
|
||||
|
||||
SYS_SCHED => {
|
||||
@ -794,14 +757,6 @@ impl Syscall {
|
||||
Self::setpgid(pid, pgid)
|
||||
}
|
||||
|
||||
SYS_RT_SIGPROCMASK => {
|
||||
let how = args[0] as i32;
|
||||
let nset = args[1];
|
||||
let oset = args[2];
|
||||
let sigsetsize = args[3];
|
||||
Self::rt_sigprocmask(how, nset, oset, sigsetsize)
|
||||
}
|
||||
|
||||
SYS_TKILL => {
|
||||
warn!("SYS_TKILL has not yet been implemented");
|
||||
Ok(0)
|
||||
@ -1053,33 +1008,6 @@ impl Syscall {
|
||||
let second = args[0] as u32;
|
||||
Self::alarm(second)
|
||||
}
|
||||
|
||||
SYS_SHMGET => {
|
||||
let key = ShmKey::new(args[0]);
|
||||
let size = args[1];
|
||||
let shmflg = ShmFlags::from_bits_truncate(args[2] as u32);
|
||||
|
||||
Self::shmget(key, size, shmflg)
|
||||
}
|
||||
SYS_SHMAT => {
|
||||
let id = ShmId::new(args[0]);
|
||||
let vaddr = VirtAddr::new(args[1]);
|
||||
let shmflg = ShmFlags::from_bits_truncate(args[2] as u32);
|
||||
|
||||
Self::shmat(id, vaddr, shmflg)
|
||||
}
|
||||
SYS_SHMDT => {
|
||||
let vaddr = VirtAddr::new(args[0]);
|
||||
Self::shmdt(vaddr)
|
||||
}
|
||||
SYS_SHMCTL => {
|
||||
let id = ShmId::new(args[0]);
|
||||
let cmd = ShmCtlCmd::from(args[1]);
|
||||
let user_buf = args[2] as *const u8;
|
||||
let from_user = frame.is_from_user();
|
||||
|
||||
Self::shmctl(id, cmd, user_buf, from_user)
|
||||
}
|
||||
SYS_MSYNC => {
|
||||
let start = page_align_up(args[0]);
|
||||
let len = page_align_up(args[1]);
|
||||
@ -1131,8 +1059,7 @@ impl Syscall {
|
||||
}
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
SYS_SETRLIMIT => Ok(0),
|
||||
SYS_RESTART_SYSCALL => Self::restart_syscall(),
|
||||
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user