mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-20 05:56:32 +00:00
新增系统调用,并对照linux-6.1.9改写sys_wait4 (#440)
* 1. 新增以下系统调用 - SYS_LSTAT - SYS_READV - SYS_ACCESS - SYS_UNLINK - SYS_CHMOD - SYS_FCHMOD - SYS_UMASK - SYS_SYSINFO - SYS_CLOCK_GETTIME - SYS_FCHMODAT - SYS_FACCESSAT 2. 修改sys_wait4,使得其部分符合Linux的行为(还是有些地方不符合的,详情请对比linux-6.1.9的sys_wait4接口)
This commit is contained in:
57
kernel/src/syscall/misc.rs
Normal file
57
kernel/src/syscall/misc.rs
Normal file
@ -0,0 +1,57 @@
|
||||
use crate::arch::mm::LockedFrameAllocator;
|
||||
|
||||
use super::{user_access::UserBufferWriter, Syscall, SystemError};
|
||||
|
||||
#[repr(C)]
|
||||
|
||||
/// 系统信息
|
||||
///
|
||||
/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/include/uapi/linux/sysinfo.h#8
|
||||
#[derive(Debug, Default, Copy, Clone)]
|
||||
pub struct SysInfo {
|
||||
uptime: u64,
|
||||
loads: [u64; 3],
|
||||
totalram: u64,
|
||||
freeram: u64,
|
||||
sharedram: u64,
|
||||
bufferram: u64,
|
||||
totalswap: u64,
|
||||
freeswap: u64,
|
||||
procs: u16,
|
||||
pad: u16,
|
||||
totalhigh: u64,
|
||||
freehigh: u64,
|
||||
mem_unit: u32,
|
||||
// 这后面还有一小段,但是我们不需要
|
||||
}
|
||||
|
||||
impl Syscall {
|
||||
pub fn sysinfo(info: *mut SysInfo) -> Result<usize, SystemError> {
|
||||
let mut writer = UserBufferWriter::new(info, core::mem::size_of::<SysInfo>(), true)?;
|
||||
let mut sysinfo = SysInfo::default();
|
||||
|
||||
let mem = LockedFrameAllocator.get_usage();
|
||||
sysinfo.uptime = 0;
|
||||
sysinfo.loads = [0; 3];
|
||||
sysinfo.totalram = mem.total().bytes() as u64;
|
||||
sysinfo.freeram = mem.free().bytes() as u64;
|
||||
sysinfo.sharedram = 0;
|
||||
sysinfo.bufferram = 0;
|
||||
sysinfo.totalswap = 0;
|
||||
sysinfo.freeswap = 0;
|
||||
sysinfo.procs = 0;
|
||||
sysinfo.pad = 0;
|
||||
sysinfo.totalhigh = 0;
|
||||
sysinfo.freehigh = 0;
|
||||
sysinfo.mem_unit = 0;
|
||||
|
||||
writer.copy_one_to_user(&sysinfo, 0)?;
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub fn umask(_mask: u32) -> Result<usize, SystemError> {
|
||||
kwarn!("SYS_UMASK has not yet been implemented\n");
|
||||
return Ok(0o777);
|
||||
}
|
||||
}
|
@ -4,7 +4,10 @@ use core::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
arch::syscall::{SYS_ACCESS, SYS_FACCESSAT, SYS_FACCESSAT2, SYS_PRLIMIT64},
|
||||
arch::syscall::{
|
||||
SYS_ACCESS, SYS_CHMOD, SYS_CLOCK_GETTIME, SYS_FACCESSAT, SYS_FACCESSAT2, SYS_FCHMOD,
|
||||
SYS_FCHMODAT, SYS_LSTAT, SYS_PRLIMIT64, SYS_READV, SYS_SYSINFO, SYS_UMASK, SYS_UNLINK,
|
||||
},
|
||||
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
||||
process::{
|
||||
fork::KernelCloneArgs,
|
||||
@ -35,8 +38,12 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
use self::user_access::{UserBufferReader, UserBufferWriter};
|
||||
use self::{
|
||||
misc::SysInfo,
|
||||
user_access::{UserBufferReader, UserBufferWriter},
|
||||
};
|
||||
|
||||
pub mod misc;
|
||||
pub mod user_access;
|
||||
|
||||
#[repr(i32)]
|
||||
@ -317,6 +324,9 @@ pub enum SystemError {
|
||||
EVMPRTLDFailed = 135,
|
||||
EVMLAUNCHFailed = 136,
|
||||
KVM_HVA_ERR_BAD = 137,
|
||||
|
||||
// === 以下错误码不应该被用户态程序使用 ===
|
||||
ERESTARTSYS = 512,
|
||||
}
|
||||
|
||||
impl SystemError {
|
||||
@ -383,7 +393,6 @@ pub const SYS_SOCKET_PAIR: usize = 53;
|
||||
pub const SYS_SETSOCKOPT: usize = 54;
|
||||
pub const SYS_GETSOCKOPT: usize = 55;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub const SYS_CLONE: usize = 56;
|
||||
pub const SYS_FORK: usize = 57;
|
||||
pub const SYS_VFORK: usize = 58;
|
||||
@ -507,7 +516,7 @@ impl Syscall {
|
||||
|
||||
let flags = args[1];
|
||||
let open_flags: FileMode = FileMode::from_bits_truncate(flags as u32);
|
||||
Self::open(path, open_flags)
|
||||
Self::open(path, open_flags, true)
|
||||
};
|
||||
res
|
||||
}
|
||||
@ -657,13 +666,13 @@ impl Syscall {
|
||||
}
|
||||
}
|
||||
SYS_WAIT4 => {
|
||||
let pid = args[0] as i64;
|
||||
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)
|
||||
Self::wait4(pid.into(), wstatus, options, rusage)
|
||||
}
|
||||
|
||||
SYS_EXIT => {
|
||||
@ -754,6 +763,11 @@ impl Syscall {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SYS_UNLINK => {
|
||||
let pathname = args[0] as *const u8;
|
||||
Self::unlink(pathname)
|
||||
}
|
||||
SYS_KILL => {
|
||||
let pid = Pid::new(args[0]);
|
||||
let sig = args[1] as c_int;
|
||||
@ -1093,13 +1107,14 @@ impl Syscall {
|
||||
Self::do_futex(uaddr, operation, val, timespec, uaddr2, utime as u32, val3)
|
||||
}
|
||||
|
||||
SYS_READV => Self::readv(args[0] as i32, args[1], args[2]),
|
||||
SYS_WRITEV => Self::writev(args[0] as i32, args[1], args[2]),
|
||||
|
||||
SYS_ARCH_PRCTL => Self::arch_prctl(args[0], args[1]),
|
||||
|
||||
SYS_SET_TID_ADDR => Self::set_tid_address(args[0]),
|
||||
|
||||
SYS_STAT => {
|
||||
SYS_STAT | SYS_LSTAT => {
|
||||
let path: &CStr = unsafe { CStr::from_ptr(args[0] as *const c_char) };
|
||||
let path: Result<&str, core::str::Utf8Error> = path.to_str();
|
||||
let res = if path.is_err() {
|
||||
@ -1109,7 +1124,13 @@ impl Syscall {
|
||||
let kstat = args[1] as *mut PosixKstat;
|
||||
let vaddr = VirtAddr::new(kstat as usize);
|
||||
match verify_area(vaddr, core::mem::size_of::<PosixKstat>()) {
|
||||
Ok(_) => Self::stat(path, kstat),
|
||||
Ok(_) => {
|
||||
if syscall_num == SYS_STAT {
|
||||
Self::stat(path, kstat)
|
||||
} else {
|
||||
Self::lstat(path, kstat)
|
||||
}
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
};
|
||||
@ -1225,6 +1246,39 @@ impl Syscall {
|
||||
Self::faccessat2(dirfd, pathname, mode, flags)
|
||||
}
|
||||
|
||||
SYS_CLOCK_GETTIME => {
|
||||
let clockid = args[0] as i32;
|
||||
let timespec = args[1] as *mut TimeSpec;
|
||||
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_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)
|
||||
}
|
||||
|
||||
_ => panic!("Unsupported syscall ID: {}", syscall_num),
|
||||
};
|
||||
return r;
|
||||
|
@ -223,6 +223,17 @@ impl<'a> UserBufferReader<'a> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
/// 把用户空间的数据转换成指定类型的切片
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `offset`:字节偏移量
|
||||
pub fn buffer<T>(&self, offset: usize) -> Result<&[T], SystemError> {
|
||||
Ok(self
|
||||
.convert_with_offset::<T>(self.buffer, offset)
|
||||
.map_err(|_| SystemError::EINVAL)?)
|
||||
}
|
||||
|
||||
fn convert_with_offset<T>(&self, src: &[u8], offset: usize) -> Result<&[T], SystemError> {
|
||||
if offset >= src.len() {
|
||||
return Err(SystemError::EINVAL);
|
||||
|
Reference in New Issue
Block a user