mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 10:15:03 +00:00
* feat:补充wait4的逻辑,添加对进程组的判断 * fix: 修复进程退出码的返回,将正常退出的进程的退出码移动至高8位 * fix: 移除session和processgroup的debug trait Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * fix: 删除shell.service文件中对于backspace的单独设置 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> * fix: 更新exit函数文档,明确状态码移位规则 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com> --------- Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
1257 lines
45 KiB
Rust
1257 lines
45 KiB
Rust
use core::{
|
||
ffi::{c_int, c_void},
|
||
sync::atomic::{AtomicBool, Ordering},
|
||
};
|
||
|
||
use crate::{
|
||
arch::{ipc::signal::SigSet, 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,
|
||
process::{
|
||
fork::KernelCloneArgs,
|
||
process_group::Pgid,
|
||
resource::{RLimit64, RUsage},
|
||
ProcessFlags, ProcessManager,
|
||
},
|
||
sched::{schedule, SchedMode},
|
||
syscall::user_access::check_and_clone_cstr,
|
||
};
|
||
|
||
use log::{info, warn};
|
||
use num_traits::FromPrimitive;
|
||
use system_error::SystemError;
|
||
use table::{syscall_table, syscall_table_init};
|
||
|
||
use crate::{
|
||
arch::{interrupt::TrapFrame, MMArch},
|
||
filesystem::vfs::{
|
||
fcntl::{AtFlags, FcntlCommand},
|
||
file::FileMode,
|
||
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,
|
||
},
|
||
};
|
||
|
||
use self::{
|
||
misc::SysInfo,
|
||
user_access::{UserBufferReader, UserBufferWriter},
|
||
};
|
||
|
||
pub mod misc;
|
||
pub mod table;
|
||
pub mod user_access;
|
||
|
||
// 与linux不一致的调用,在linux基础上累加
|
||
pub const SYS_PUT_STRING: usize = 100000;
|
||
pub const SYS_SBRK: usize = 100001;
|
||
/// todo: 该系统调用与Linux不一致,将来需要删除该系统调用!!! 删的时候记得改C版本的libc
|
||
pub const SYS_CLOCK: usize = 100002;
|
||
pub const SYS_SCHED: usize = 100003;
|
||
|
||
#[derive(Debug)]
|
||
pub struct Syscall;
|
||
|
||
impl Syscall {
|
||
/// 初始化系统调用
|
||
#[inline(never)]
|
||
pub fn init() -> Result<(), SystemError> {
|
||
static INIT_FLAG: AtomicBool = AtomicBool::new(false);
|
||
let prev = INIT_FLAG.swap(true, Ordering::SeqCst);
|
||
if prev {
|
||
panic!("Cannot initialize syscall more than once!");
|
||
}
|
||
info!("Initializing syscall...");
|
||
let r = crate::arch::syscall::arch_syscall_init();
|
||
info!("Syscall init successfully!");
|
||
|
||
return r;
|
||
}
|
||
/// 系统调用分发器,用于分发系统调用。
|
||
///
|
||
/// 与[handle]不同,这个函数会捕获系统调用处理函数的panic,返回错误码。
|
||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||
pub fn catch_handle(
|
||
syscall_num: usize,
|
||
args: &[usize],
|
||
frame: &mut TrapFrame,
|
||
) -> Result<usize, SystemError> {
|
||
use crate::debug::panic::kernel_catch_unwind;
|
||
let res = kernel_catch_unwind(|| Self::handle(syscall_num, args, frame))?;
|
||
res
|
||
}
|
||
/// @brief 系统调用分发器,用于分发系统调用。
|
||
///
|
||
/// 这个函数内,需要根据系统调用号,调用对应的系统调用处理函数。
|
||
/// 并且,对于用户态传入的指针参数,需要在本函数内进行越界检查,防止访问到内核空间。
|
||
#[inline(never)]
|
||
pub fn handle(
|
||
syscall_num: usize,
|
||
args: &[usize],
|
||
frame: &mut TrapFrame,
|
||
) -> Result<usize, SystemError> {
|
||
// 首先尝试从syscall_table获取处理函数
|
||
if let Some(handler) = syscall_table().get(syscall_num) {
|
||
// 使用以下代码可以打印系统调用号和参数,方便调试
|
||
// log::debug!(
|
||
// "Syscall {} called with args {}",
|
||
// handler.name,
|
||
// handler.args_string(args)
|
||
// );
|
||
return handler.inner_handle.handle(args, frame.is_from_user());
|
||
}
|
||
|
||
// 如果找不到,fallback到原有逻辑
|
||
let r = match syscall_num {
|
||
SYS_PUT_STRING => {
|
||
Self::put_string(args[0] as *const u8, args[1] as u32, args[2] as u32)
|
||
}
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_OPEN => {
|
||
let path = args[0] as *const u8;
|
||
let flags = args[1] as u32;
|
||
let mode = args[2] as u32;
|
||
|
||
Self::open(path, flags, mode, true)
|
||
}
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_RENAME => {
|
||
let oldname: *const u8 = args[0] as *const u8;
|
||
let newname: *const u8 = args[1] as *const u8;
|
||
Self::do_renameat2(
|
||
AtFlags::AT_FDCWD.bits(),
|
||
oldname,
|
||
AtFlags::AT_FDCWD.bits(),
|
||
newname,
|
||
0,
|
||
)
|
||
}
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_RENAMEAT => {
|
||
let oldfd = args[0] as i32;
|
||
let oldname: *const u8 = args[1] as *const u8;
|
||
let newfd = args[2] as i32;
|
||
let newname: *const u8 = args[3] as *const u8;
|
||
Self::do_renameat2(oldfd, oldname, newfd, newname, 0)
|
||
}
|
||
|
||
SYS_RENAMEAT2 => {
|
||
let oldfd = args[0] as i32;
|
||
let oldname: *const u8 = args[1] as *const u8;
|
||
let newfd = args[2] as i32;
|
||
let newname: *const u8 = args[3] as *const u8;
|
||
let flags = args[4] as u32;
|
||
Self::do_renameat2(oldfd, oldname, newfd, newname, flags)
|
||
}
|
||
|
||
SYS_OPENAT => {
|
||
let dirfd = args[0] as i32;
|
||
let path = args[1] as *const u8;
|
||
let flags = args[2] as u32;
|
||
let mode = args[3] as u32;
|
||
|
||
Self::openat(dirfd, path, flags, mode, true)
|
||
}
|
||
SYS_CLOSE => {
|
||
let fd = args[0];
|
||
Self::close(fd)
|
||
}
|
||
|
||
SYS_LSEEK => {
|
||
let fd = args[0] as i32;
|
||
let offset = args[1] as i64;
|
||
let whence = args[2] as u32;
|
||
|
||
Self::lseek(fd, offset, whence)
|
||
}
|
||
|
||
SYS_PREAD64 => {
|
||
let fd = args[0] as i32;
|
||
let buf_vaddr = args[1];
|
||
let len = args[2];
|
||
let offset = args[3];
|
||
|
||
let mut user_buffer_writer =
|
||
UserBufferWriter::new(buf_vaddr as *mut u8, len, frame.is_from_user())?;
|
||
let buf = user_buffer_writer.buffer(0)?;
|
||
Self::pread(fd, buf, len, offset)
|
||
}
|
||
|
||
SYS_PWRITE64 => {
|
||
let fd = args[0] as i32;
|
||
let buf_vaddr = args[1];
|
||
let len = args[2];
|
||
let offset = args[3];
|
||
|
||
let user_buffer_reader =
|
||
UserBufferReader::new(buf_vaddr as *const u8, len, frame.is_from_user())?;
|
||
|
||
let buf = user_buffer_reader.read_from_user(0)?;
|
||
Self::pwrite(fd, buf, len, offset)
|
||
}
|
||
|
||
SYS_IOCTL => {
|
||
let fd = args[0];
|
||
let cmd = args[1];
|
||
let data = args[2];
|
||
Self::ioctl(fd, cmd as u32, data)
|
||
}
|
||
|
||
#[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())
|
||
}
|
||
|
||
SYS_SBRK => {
|
||
let increment = args[0] as isize;
|
||
Self::sbrk(increment).map(|vaddr: VirtAddr| vaddr.data())
|
||
}
|
||
|
||
SYS_REBOOT => {
|
||
let magic1 = args[0] as u32;
|
||
let magic2 = args[1] as u32;
|
||
let cmd = args[2] as u32;
|
||
let arg = args[3];
|
||
Self::reboot(magic1, magic2, cmd, arg)
|
||
}
|
||
|
||
SYS_CHDIR => {
|
||
let r = args[0] as *const u8;
|
||
Self::chdir(r)
|
||
}
|
||
SYS_FCHDIR => {
|
||
let fd = args[0] as i32;
|
||
Self::fchdir(fd)
|
||
}
|
||
|
||
#[allow(unreachable_patterns)]
|
||
SYS_GETDENTS64 | SYS_GETDENTS => {
|
||
let fd = args[0] as i32;
|
||
|
||
let buf_vaddr = args[1];
|
||
let len = args[2];
|
||
let virt_addr: VirtAddr = VirtAddr::new(buf_vaddr);
|
||
// 判断缓冲区是否来自用户态,进行权限校验
|
||
let res = if frame.is_from_user() && verify_area(virt_addr, len).is_err() {
|
||
// 来自用户态,而buffer在内核态,这样的操作不被允许
|
||
Err(SystemError::EPERM)
|
||
} else if buf_vaddr == 0 {
|
||
Err(SystemError::EFAULT)
|
||
} else {
|
||
let buf: &mut [u8] = unsafe {
|
||
core::slice::from_raw_parts_mut::<'static, u8>(buf_vaddr as *mut u8, len)
|
||
};
|
||
Self::getdents(fd, buf)
|
||
};
|
||
|
||
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;
|
||
let mode = args[1];
|
||
|
||
Self::mkdir(path, mode)
|
||
}
|
||
|
||
SYS_MKDIRAT => {
|
||
let dirfd = args[0] as i32;
|
||
let path = args[1] as *const u8;
|
||
let mode = args[2];
|
||
Self::mkdir_at(dirfd, path, mode)
|
||
}
|
||
|
||
SYS_NANOSLEEP => {
|
||
let req = args[0] as *const PosixTimeSpec;
|
||
let rem = args[1] as *mut PosixTimeSpec;
|
||
let virt_req = VirtAddr::new(req as usize);
|
||
let virt_rem = VirtAddr::new(rem as usize);
|
||
if frame.is_from_user()
|
||
&& (verify_area(virt_req, core::mem::size_of::<PosixTimeSpec>()).is_err()
|
||
|| verify_area(virt_rem, core::mem::size_of::<PosixTimeSpec>()).is_err())
|
||
{
|
||
Err(SystemError::EFAULT)
|
||
} else {
|
||
Self::nanosleep(req, rem)
|
||
}
|
||
}
|
||
|
||
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;
|
||
let flags = args[2] as u32;
|
||
Self::unlinkat(dirfd, path, flags)
|
||
}
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_SYMLINK => {
|
||
let oldname = args[0] as *const u8;
|
||
let newname = args[1] as *const u8;
|
||
Self::symlink(oldname, newname)
|
||
}
|
||
|
||
SYS_SYMLINKAT => {
|
||
let oldname = args[0] as *const u8;
|
||
let newdfd = args[1] as i32;
|
||
let newname = args[2] as *const u8;
|
||
Self::symlinkat(oldname, newdfd, newname)
|
||
}
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_RMDIR => {
|
||
let path = args[0] as *const u8;
|
||
Self::rmdir(path)
|
||
}
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_LINK => {
|
||
let old = args[0] as *const u8;
|
||
let new = args[1] as *const u8;
|
||
return Self::link(old, new);
|
||
}
|
||
|
||
SYS_LINKAT => {
|
||
let oldfd = args[0] as i32;
|
||
let old = args[1] as *const u8;
|
||
let newfd = args[2] as i32;
|
||
let new = args[3] as *const u8;
|
||
let flags = args[4] as i32;
|
||
return Self::linkat(oldfd, old, newfd, new, flags);
|
||
}
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_UNLINK => {
|
||
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 => {
|
||
warn!("syscall sched");
|
||
schedule(SchedMode::SM_NONE);
|
||
Ok(0)
|
||
}
|
||
SYS_DUP => {
|
||
let oldfd: i32 = args[0] as c_int;
|
||
Self::dup(oldfd)
|
||
}
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_DUP2 => {
|
||
let oldfd: i32 = args[0] as c_int;
|
||
let newfd: i32 = args[1] as c_int;
|
||
Self::dup2(oldfd, newfd)
|
||
}
|
||
|
||
SYS_DUP3 => {
|
||
let oldfd: i32 = args[0] as c_int;
|
||
let newfd: i32 = args[1] as c_int;
|
||
let flags: u32 = args[2] as u32;
|
||
Self::dup3(oldfd, newfd, flags)
|
||
}
|
||
|
||
SYS_SOCKET => Self::socket(args[0], args[1], args[2]),
|
||
SYS_SETSOCKOPT => {
|
||
let optval = args[3] as *const u8;
|
||
let optlen = args[4];
|
||
let virt_optval = VirtAddr::new(optval as usize);
|
||
// 验证optval的地址是否合法
|
||
if verify_area(virt_optval, optlen).is_err() {
|
||
// 地址空间超出了用户空间的范围,不合法
|
||
Err(SystemError::EFAULT)
|
||
} else {
|
||
let data: &[u8] = unsafe { core::slice::from_raw_parts(optval, optlen) };
|
||
Self::setsockopt(args[0], args[1], args[2], data)
|
||
}
|
||
}
|
||
SYS_GETSOCKOPT => {
|
||
let optval = args[3] as *mut u8;
|
||
let optlen = args[4] as *mut usize;
|
||
let virt_optval = VirtAddr::new(optval as usize);
|
||
let virt_optlen = VirtAddr::new(optlen as usize);
|
||
let security_check = || {
|
||
// 验证optval的地址是否合法
|
||
if verify_area(virt_optval, PAGE_4K_SIZE).is_err() {
|
||
// 地址空间超出了用户空间的范围,不合法
|
||
return Err(SystemError::EFAULT);
|
||
}
|
||
|
||
// 验证optlen的地址是否合法
|
||
if verify_area(virt_optlen, core::mem::size_of::<u32>()).is_err() {
|
||
// 地址空间超出了用户空间的范围,不合法
|
||
return Err(SystemError::EFAULT);
|
||
}
|
||
return Ok(());
|
||
};
|
||
let r = security_check();
|
||
if let Err(e) = r {
|
||
Err(e)
|
||
} else {
|
||
Self::getsockopt(args[0], args[1], args[2], optval, optlen as *mut u32)
|
||
}
|
||
}
|
||
|
||
SYS_CONNECT => {
|
||
let addr = args[1] as *const SockAddr;
|
||
let addrlen = args[2];
|
||
let virt_addr = VirtAddr::new(addr as usize);
|
||
// 验证addr的地址是否合法
|
||
if verify_area(virt_addr, addrlen).is_err() {
|
||
// 地址空间超出了用户空间的范围,不合法
|
||
Err(SystemError::EFAULT)
|
||
} else {
|
||
Self::connect(args[0], addr, addrlen)
|
||
}
|
||
}
|
||
SYS_BIND => {
|
||
let addr = args[1] as *const SockAddr;
|
||
let addrlen = args[2];
|
||
let virt_addr = VirtAddr::new(addr as usize);
|
||
// 验证addr的地址是否合法
|
||
if verify_area(virt_addr, addrlen).is_err() {
|
||
// 地址空间超出了用户空间的范围,不合法
|
||
Err(SystemError::EFAULT)
|
||
} else {
|
||
Self::bind(args[0], addr, addrlen)
|
||
}
|
||
}
|
||
|
||
SYS_SENDTO => {
|
||
let buf = args[1] as *const u8;
|
||
let len = args[2];
|
||
let flags = args[3] as u32;
|
||
let addr = args[4] as *const SockAddr;
|
||
let addrlen = args[5];
|
||
let virt_buf = VirtAddr::new(buf as usize);
|
||
let virt_addr = VirtAddr::new(addr as usize);
|
||
// 验证buf的地址是否合法
|
||
if verify_area(virt_buf, len).is_err() || verify_area(virt_addr, addrlen).is_err() {
|
||
// 地址空间超出了用户空间的范围,不合法
|
||
Err(SystemError::EFAULT)
|
||
} else {
|
||
let data: &[u8] = unsafe { core::slice::from_raw_parts(buf, len) };
|
||
Self::sendto(args[0], data, flags, addr, addrlen)
|
||
}
|
||
}
|
||
|
||
SYS_RECVFROM => {
|
||
let buf = args[1] as *mut u8;
|
||
let len = args[2];
|
||
let flags = args[3] as u32;
|
||
let addr = args[4] as *mut SockAddr;
|
||
let addrlen = args[5] as *mut usize;
|
||
let virt_buf = VirtAddr::new(buf as usize);
|
||
let virt_addrlen = VirtAddr::new(addrlen as usize);
|
||
let virt_addr = VirtAddr::new(addr as usize);
|
||
let security_check = || {
|
||
// 验证buf的地址是否合法
|
||
if verify_area(virt_buf, len).is_err() {
|
||
// 地址空间超出了用户空间的范围,不合法
|
||
return Err(SystemError::EFAULT);
|
||
}
|
||
|
||
// 验证addrlen的地址是否合法
|
||
if verify_area(virt_addrlen, core::mem::size_of::<u32>()).is_err() {
|
||
// 地址空间超出了用户空间的范围,不合法
|
||
return Err(SystemError::EFAULT);
|
||
}
|
||
|
||
if verify_area(virt_addr, core::mem::size_of::<SockAddr>()).is_err() {
|
||
// 地址空间超出了用户空间的范围,不合法
|
||
return Err(SystemError::EFAULT);
|
||
}
|
||
return Ok(());
|
||
};
|
||
let r = security_check();
|
||
if let Err(e) = r {
|
||
Err(e)
|
||
} else {
|
||
let buf = unsafe { core::slice::from_raw_parts_mut(buf, len) };
|
||
Self::recvfrom(args[0], buf, flags, addr, addrlen as *mut u32)
|
||
}
|
||
}
|
||
|
||
SYS_RECVMSG => {
|
||
let msg = args[1] as *mut MsgHdr;
|
||
let flags = args[2] as u32;
|
||
|
||
let mut user_buffer_writer = UserBufferWriter::new(
|
||
msg,
|
||
core::mem::size_of::<MsgHdr>(),
|
||
frame.is_from_user(),
|
||
)?;
|
||
let buffer = user_buffer_writer.buffer::<MsgHdr>(0)?;
|
||
|
||
let msg = &mut buffer[0];
|
||
Self::recvmsg(args[0], msg, flags)
|
||
}
|
||
|
||
SYS_LISTEN => Self::listen(args[0], args[1]),
|
||
SYS_SHUTDOWN => Self::shutdown(args[0], args[1]),
|
||
SYS_ACCEPT => Self::accept(args[0], args[1] as *mut SockAddr, args[2] as *mut u32),
|
||
SYS_ACCEPT4 => Self::accept4(
|
||
args[0],
|
||
args[1] as *mut SockAddr,
|
||
args[2] as *mut u32,
|
||
args[3] as u32,
|
||
),
|
||
SYS_GETSOCKNAME => {
|
||
Self::getsockname(args[0], args[1] as *mut SockAddr, args[2] as *mut u32)
|
||
}
|
||
SYS_GETPEERNAME => {
|
||
Self::getpeername(args[0], args[1] as *mut SockAddr, args[2] as *mut u32)
|
||
}
|
||
SYS_GETTIMEOFDAY => {
|
||
let timeval = args[0] as *mut PosixTimeval;
|
||
let timezone_ptr = args[1] as *mut PosixTimeZone;
|
||
Self::gettimeofday(timeval, timezone_ptr)
|
||
}
|
||
SYS_MMAP => {
|
||
let len = page_align_up(args[1]);
|
||
let virt_addr = VirtAddr::new(args[0]);
|
||
if verify_area(virt_addr, len).is_err() {
|
||
Err(SystemError::EFAULT)
|
||
} else {
|
||
Self::mmap(
|
||
VirtAddr::new(args[0]),
|
||
len,
|
||
args[2],
|
||
args[3],
|
||
args[4] as i32,
|
||
args[5],
|
||
)
|
||
}
|
||
}
|
||
SYS_MREMAP => {
|
||
let old_vaddr = VirtAddr::new(args[0]);
|
||
let old_len = args[1];
|
||
let new_len = args[2];
|
||
let mremap_flags = MremapFlags::from_bits_truncate(args[3] as u8);
|
||
let new_vaddr = VirtAddr::new(args[4]);
|
||
|
||
Self::mremap(old_vaddr, old_len, new_len, mremap_flags, new_vaddr)
|
||
}
|
||
SYS_MUNMAP => {
|
||
let addr = args[0];
|
||
let len = page_align_up(args[1]);
|
||
if addr & (MMArch::PAGE_SIZE - 1) != 0 {
|
||
// The addr argument is not a multiple of the page size
|
||
Err(SystemError::EINVAL)
|
||
} else {
|
||
Self::munmap(VirtAddr::new(addr), len)
|
||
}
|
||
}
|
||
SYS_MPROTECT => {
|
||
let addr = args[0];
|
||
let len = page_align_up(args[1]);
|
||
if addr & (MMArch::PAGE_SIZE - 1) != 0 {
|
||
// The addr argument is not a multiple of the page size
|
||
Err(SystemError::EINVAL)
|
||
} else {
|
||
Self::mprotect(VirtAddr::new(addr), len, args[2])
|
||
}
|
||
}
|
||
|
||
SYS_GETCWD => {
|
||
let buf = args[0] as *mut u8;
|
||
let size = args[1];
|
||
let security_check = || {
|
||
verify_area(VirtAddr::new(buf as usize), size)?;
|
||
return Ok(());
|
||
};
|
||
let r = security_check();
|
||
if let Err(e) = r {
|
||
Err(e)
|
||
} else {
|
||
let buf = unsafe { core::slice::from_raw_parts_mut(buf, size) };
|
||
Self::getcwd(buf).map(|ptr| ptr.data())
|
||
}
|
||
}
|
||
|
||
SYS_GETPGID => Self::getpgid(Pid::new(args[0])).map(|pgid| pgid.into()),
|
||
|
||
SYS_GETPPID => Self::getppid().map(|pid| pid.into()),
|
||
|
||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||
SYS_FSTAT => {
|
||
let fd = args[0] as i32;
|
||
Self::fstat(fd, args[1])
|
||
}
|
||
|
||
SYS_FCNTL => {
|
||
let fd = args[0] as i32;
|
||
let cmd: Option<FcntlCommand> =
|
||
<FcntlCommand as FromPrimitive>::from_u32(args[1] as u32);
|
||
let arg = args[2] as i32;
|
||
let res = if let Some(cmd) = cmd {
|
||
Self::fcntl(fd, cmd, arg)
|
||
} else {
|
||
Err(SystemError::EINVAL)
|
||
};
|
||
|
||
// debug!("FCNTL: fd: {}, cmd: {:?}, arg: {}, res: {:?}", fd, cmd, arg, res);
|
||
res
|
||
}
|
||
|
||
SYS_FTRUNCATE => {
|
||
let fd = args[0] as i32;
|
||
let len = args[1];
|
||
let res = Self::ftruncate(fd, len);
|
||
// debug!("FTRUNCATE: fd: {}, len: {}, res: {:?}", fd, len, res);
|
||
res
|
||
}
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_MKNOD => {
|
||
let path = args[0];
|
||
let flags = args[1];
|
||
let dev_t = args[2];
|
||
let flags: ModeType = ModeType::from_bits_truncate(flags as u32);
|
||
Self::mknod(
|
||
path as *const u8,
|
||
flags,
|
||
crate::driver::base::device::device_number::DeviceNumber::from(dev_t as u32),
|
||
)
|
||
}
|
||
|
||
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)?;
|
||
let val = args[2] as u32;
|
||
let utime = args[3];
|
||
let uaddr2 = VirtAddr::new(args[4]);
|
||
let val3 = args[5] as u32;
|
||
|
||
let mut timespec = None;
|
||
if utime != 0 && operation.contains(FutexFlag::FLAGS_HAS_TIMEOUT) {
|
||
let reader = UserBufferReader::new(
|
||
utime as *const PosixTimeSpec,
|
||
core::mem::size_of::<PosixTimeSpec>(),
|
||
true,
|
||
)?;
|
||
|
||
timespec = Some(*reader.read_one_from_user::<PosixTimeSpec>(0)?);
|
||
}
|
||
|
||
Self::do_futex(uaddr, operation, val, timespec, uaddr2, utime as u32, val3)
|
||
}
|
||
|
||
SYS_SET_ROBUST_LIST => {
|
||
let head = args[0];
|
||
let head_uaddr = VirtAddr::new(head);
|
||
let len = args[1];
|
||
|
||
let ret = Self::set_robust_list(head_uaddr, len);
|
||
return ret;
|
||
}
|
||
|
||
SYS_GET_ROBUST_LIST => {
|
||
let pid = args[0];
|
||
let head = args[1];
|
||
let head_uaddr = VirtAddr::new(head);
|
||
let len_ptr = args[2];
|
||
let len_ptr_uaddr = VirtAddr::new(len_ptr);
|
||
|
||
let ret = Self::get_robust_list(pid, head_uaddr, len_ptr_uaddr);
|
||
return ret;
|
||
}
|
||
|
||
SYS_SET_TID_ADDRESS => Self::set_tid_address(args[0]),
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_LSTAT => {
|
||
let path = args[0] as *const u8;
|
||
Self::lstat(path, args[1])
|
||
}
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_STAT => {
|
||
let path = args[0] as *const u8;
|
||
Self::stat(path, args[1])
|
||
}
|
||
|
||
SYS_STATFS => {
|
||
let path = args[0] as *const u8;
|
||
let statfs = args[1] as *mut PosixStatfs;
|
||
Self::statfs(path, statfs)
|
||
}
|
||
|
||
SYS_FSTATFS => {
|
||
let fd = args[0] as i32;
|
||
let statfs = args[1] as *mut PosixStatfs;
|
||
Self::fstatfs(fd, statfs)
|
||
}
|
||
|
||
SYS_STATX => Self::statx(
|
||
args[0] as i32,
|
||
args[1],
|
||
args[2] as u32,
|
||
args[3] as u32,
|
||
args[4],
|
||
),
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_EPOLL_CREATE => Self::epoll_create(args[0] as i32),
|
||
SYS_EPOLL_CREATE1 => Self::epoll_create1(args[0]),
|
||
|
||
SYS_EPOLL_CTL => Self::epoll_ctl(
|
||
args[0] as i32,
|
||
args[1],
|
||
args[2] as i32,
|
||
VirtAddr::new(args[3]),
|
||
),
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_EPOLL_WAIT => Self::epoll_wait(
|
||
args[0] as i32,
|
||
VirtAddr::new(args[1]),
|
||
args[2] as i32,
|
||
args[3] as i32,
|
||
),
|
||
|
||
SYS_EPOLL_PWAIT => {
|
||
let epfd = args[0] as i32;
|
||
let epoll_event = VirtAddr::new(args[1]);
|
||
let max_events = args[2] as i32;
|
||
let timespec = args[3] as i32;
|
||
let sigmask_addr = args[4] as *mut SigSet;
|
||
|
||
if sigmask_addr.is_null() {
|
||
return Self::epoll_wait(epfd, epoll_event, max_events, timespec);
|
||
}
|
||
let sigmask_reader =
|
||
UserBufferReader::new(sigmask_addr, core::mem::size_of::<SigSet>(), true)?;
|
||
let mut sigmask = *sigmask_reader.read_one_from_user::<SigSet>(0)?;
|
||
|
||
Self::epoll_pwait(
|
||
args[0] as i32,
|
||
VirtAddr::new(args[1]),
|
||
args[2] as i32,
|
||
args[3] as i32,
|
||
&mut sigmask,
|
||
)
|
||
}
|
||
|
||
// 目前为了适配musl-libc,以下系统调用先这样写着
|
||
SYS_GETRANDOM => {
|
||
let flags = GRandFlags::from_bits(args[2] as u8).ok_or(SystemError::EINVAL)?;
|
||
Self::get_random(args[0] as *mut u8, args[1], flags)
|
||
}
|
||
|
||
SYS_SOCKETPAIR => {
|
||
let mut user_buffer_writer = UserBufferWriter::new(
|
||
args[3] as *mut c_int,
|
||
core::mem::size_of::<[c_int; 2]>(),
|
||
frame.is_from_user(),
|
||
)?;
|
||
let fds = user_buffer_writer.buffer::<i32>(0)?;
|
||
Self::socketpair(args[0], args[1], args[2], fds)
|
||
}
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_POLL => {
|
||
let fds = args[0];
|
||
let nfds = args[1] as u32;
|
||
let timeout = args[2] as i32;
|
||
Self::poll(fds, nfds, timeout)
|
||
}
|
||
|
||
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_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)
|
||
}
|
||
|
||
SYS_SIGALTSTACK => {
|
||
warn!("SYS_SIGALTSTACK has not yet been implemented");
|
||
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]);
|
||
if addr & (MMArch::PAGE_SIZE - 1) != 0 {
|
||
Err(SystemError::EINVAL)
|
||
} else {
|
||
Self::madvise(VirtAddr::new(addr), len, args[2])
|
||
}
|
||
}
|
||
|
||
SYS_GETTID => Self::gettid().map(|tid| tid.into()),
|
||
|
||
SYS_SYSLOG => {
|
||
let syslog_action_type = args[0];
|
||
let buf_vaddr = args[1];
|
||
let len = args[2];
|
||
let from_user = frame.is_from_user();
|
||
let mut user_buffer_writer =
|
||
UserBufferWriter::new(buf_vaddr as *mut u8, len, from_user)?;
|
||
|
||
let user_buf = user_buffer_writer.buffer(0)?;
|
||
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;
|
||
let buf = args[1] as *mut u8;
|
||
let bufsiz = args[2];
|
||
Self::readlink(path, buf, bufsiz)
|
||
}
|
||
|
||
SYS_READLINKAT => {
|
||
let dirfd = args[0] as i32;
|
||
let path = args[1] as *const u8;
|
||
let buf = args[2] as *mut u8;
|
||
let bufsiz = args[3];
|
||
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;
|
||
let mode = args[1] as u32;
|
||
Self::access(pathname, mode)
|
||
}
|
||
|
||
SYS_FACCESSAT => {
|
||
let dirfd = args[0] as i32;
|
||
let pathname = args[1] as *const u8;
|
||
let mode = args[2] as u32;
|
||
Self::faccessat2(dirfd, pathname, mode, 0)
|
||
}
|
||
|
||
SYS_FACCESSAT2 => {
|
||
let dirfd = args[0] as i32;
|
||
let pathname = args[1] as *const u8;
|
||
let mode = args[2] as u32;
|
||
let flags = args[3] as u32;
|
||
Self::faccessat2(dirfd, pathname, mode, flags)
|
||
}
|
||
|
||
SYS_CLOCK_GETTIME => {
|
||
let clockid = args[0] as i32;
|
||
let timespec = args[1] as *mut PosixTimeSpec;
|
||
Self::clock_gettime(clockid, timespec)
|
||
}
|
||
|
||
SYS_SYSINFO => {
|
||
let info = args[0] as *mut SysInfo;
|
||
Self::sysinfo(info)
|
||
}
|
||
|
||
SYS_UMASK => {
|
||
let mask = args[0] as u32;
|
||
Self::umask(mask)
|
||
}
|
||
|
||
SYS_FCHOWN => {
|
||
let dirfd = args[0] as i32;
|
||
let uid = args[1];
|
||
let gid = args[2];
|
||
Self::fchown(dirfd, uid, gid)
|
||
}
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_CHOWN => {
|
||
let pathname = args[0] as *const u8;
|
||
let uid = args[1];
|
||
let gid = args[2];
|
||
Self::chown(pathname, uid, gid)
|
||
}
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_LCHOWN => {
|
||
let pathname = args[0] as *const u8;
|
||
let uid = args[1];
|
||
let gid = args[2];
|
||
Self::lchown(pathname, uid, gid)
|
||
}
|
||
SYS_FCHOWNAT => {
|
||
let dirfd = args[0] as i32;
|
||
let pathname = args[1] as *const u8;
|
||
let uid = args[2];
|
||
let gid = args[3];
|
||
let flag = args[4] as i32;
|
||
Self::fchownat(dirfd, pathname, uid, gid, flag)
|
||
}
|
||
|
||
SYS_FSYNC => {
|
||
warn!("SYS_FSYNC has not yet been implemented");
|
||
Ok(0)
|
||
}
|
||
|
||
SYS_RSEQ => {
|
||
warn!("SYS_RSEQ has not yet been implemented");
|
||
Err(SystemError::ENOSYS)
|
||
}
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_CHMOD => {
|
||
let pathname = args[0] as *const u8;
|
||
let mode = args[1] as u32;
|
||
Self::chmod(pathname, mode)
|
||
}
|
||
SYS_FCHMOD => {
|
||
let fd = args[0] as i32;
|
||
let mode = args[1] as u32;
|
||
Self::fchmod(fd, mode)
|
||
}
|
||
SYS_FCHMODAT => {
|
||
let dirfd = args[0] as i32;
|
||
let pathname = args[1] as *const u8;
|
||
let mode = args[2] as u32;
|
||
Self::fchmodat(dirfd, pathname, mode)
|
||
}
|
||
|
||
SYS_SCHED_YIELD => Self::do_sched_yield(),
|
||
|
||
SYS_SCHED_GETAFFINITY => {
|
||
let pid = args[0] as i32;
|
||
let size = args[1];
|
||
let set_vaddr = args[2];
|
||
|
||
let mut user_buffer_writer =
|
||
UserBufferWriter::new(set_vaddr as *mut u8, size, frame.is_from_user())?;
|
||
let set: &mut [u8] = user_buffer_writer.buffer(0)?;
|
||
|
||
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: 这个系统调用还没有实现
|
||
|
||
Err(SystemError::ENOSYS)
|
||
}
|
||
|
||
SYS_MOUNT => {
|
||
let source = args[0] as *const u8;
|
||
let target = args[1] as *const u8;
|
||
let filesystemtype = args[2] as *const u8;
|
||
let mountflags = args[3];
|
||
let data = args[4] as *const u8; // 额外的mount参数,实现自己的mountdata来获取
|
||
return Self::mount(source, target, filesystemtype, mountflags, data);
|
||
}
|
||
|
||
SYS_UMOUNT2 => {
|
||
let target = args[0] as *const u8;
|
||
let flags = args[1] as i32;
|
||
Self::umount2(target, flags)?;
|
||
return Ok(0);
|
||
}
|
||
|
||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||
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: 这个系统调用还没有实现
|
||
|
||
Err(SystemError::EINVAL)
|
||
}
|
||
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_ALARM => {
|
||
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]);
|
||
let flags = args[2];
|
||
Self::msync(VirtAddr::new(start), len, flags)
|
||
}
|
||
SYS_UTIMENSAT => Self::sys_utimensat(
|
||
args[0] as i32,
|
||
args[1] as *const u8,
|
||
args[2] as *const PosixTimeSpec,
|
||
args[3] as u32,
|
||
),
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_FUTIMESAT => {
|
||
let flags = UtimensFlags::empty();
|
||
Self::sys_utimensat(
|
||
args[0] as i32,
|
||
args[1] as *const u8,
|
||
args[2] as *const PosixTimeSpec,
|
||
flags.bits(),
|
||
)
|
||
}
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_UTIMES => Self::sys_utimes(args[0] as *const u8, args[1] as *const PosixTimeval),
|
||
#[cfg(target_arch = "x86_64")]
|
||
SYS_EVENTFD => {
|
||
let initval = args[0] as u32;
|
||
Self::sys_eventfd(initval, 0)
|
||
}
|
||
SYS_EVENTFD2 => {
|
||
let initval = args[0] as u32;
|
||
let flags = args[1] as u32;
|
||
Self::sys_eventfd(initval, flags)
|
||
}
|
||
SYS_UNSHARE => Self::sys_unshare(args[0] as u64),
|
||
SYS_BPF => {
|
||
let cmd = args[0] as u32;
|
||
let attr = args[1] as *mut u8;
|
||
let size = args[2] as u32;
|
||
Self::sys_bpf(cmd, attr, size)
|
||
}
|
||
SYS_PERF_EVENT_OPEN => {
|
||
let attr = args[0] as *const u8;
|
||
let pid = args[1] as i32;
|
||
let cpu = args[2] as i32;
|
||
let group_fd = args[3] as i32;
|
||
let flags = args[4] as u32;
|
||
Self::sys_perf_event_open(attr, pid, cpu, group_fd, flags)
|
||
}
|
||
#[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)
|
||
}
|
||
_ => panic!("Unsupported syscall ID: {}", syscall_num),
|
||
};
|
||
|
||
if ProcessManager::current_pcb()
|
||
.flags()
|
||
.contains(ProcessFlags::NEED_SCHEDULE)
|
||
{
|
||
schedule(SchedMode::SM_PREEMPT);
|
||
}
|
||
|
||
return r;
|
||
}
|
||
|
||
pub fn put_string(
|
||
s: *const u8,
|
||
front_color: u32,
|
||
back_color: u32,
|
||
) -> Result<usize, SystemError> {
|
||
// todo: 删除这个系统调用
|
||
let s = check_and_clone_cstr(s, Some(4096))?
|
||
.into_string()
|
||
.map_err(|_| SystemError::EINVAL)?;
|
||
let fr = (front_color & 0x00ff0000) >> 16;
|
||
let fg = (front_color & 0x0000ff00) >> 8;
|
||
let fb = front_color & 0x000000ff;
|
||
let br = (back_color & 0x00ff0000) >> 16;
|
||
let bg = (back_color & 0x0000ff00) >> 8;
|
||
let bb = back_color & 0x000000ff;
|
||
print!("\x1B[38;2;{fr};{fg};{fb};48;2;{br};{bg};{bb}m{s}\x1B[0m");
|
||
return Ok(s.len());
|
||
}
|
||
}
|
||
|
||
#[inline(never)]
|
||
pub fn syscall_init() -> Result<(), SystemError> {
|
||
syscall_table_init()?;
|
||
Ok(())
|
||
}
|