mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 14:16:47 +00:00
fix: mkdir输出错误信息; feat: 实现get_pathname (#615)
* fix: mkdir输出错误信息; feat: 实现get_pathname * fix: 将处理路径的操作放入vfs而不是在syscall/mod.rs中 * 调整入参类型 --------- Co-authored-by: longjin <longjin@DragonOS.org>
This commit is contained in:
parent
9e481b3bfe
commit
82df0a1310
@ -4,10 +4,7 @@ use alloc::{format, string::ToString, sync::Arc};
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
driver::{
|
||||
base::block::disk_info::Partition,
|
||||
disk::ahci::{self},
|
||||
},
|
||||
driver::{base::block::disk_info::Partition, disk::ahci},
|
||||
filesystem::{
|
||||
devfs::devfs_init,
|
||||
fat::fs::FATFileSystem,
|
||||
@ -23,7 +20,7 @@ use crate::{
|
||||
use super::{
|
||||
file::FileMode,
|
||||
utils::{rsplit_path, user_path_at},
|
||||
IndexNode, InodeId, MAX_PATHLEN, VFS_MAX_FOLLOW_SYMLINK_TIMES,
|
||||
IndexNode, InodeId, VFS_MAX_FOLLOW_SYMLINK_TIMES,
|
||||
};
|
||||
|
||||
/// @brief 原子地生成新的Inode号。
|
||||
@ -181,10 +178,7 @@ pub fn mount_root_fs() -> Result<(), SystemError> {
|
||||
|
||||
/// @brief 创建文件/文件夹
|
||||
pub fn do_mkdir(path: &str, _mode: FileMode) -> Result<u64, SystemError> {
|
||||
// 文件名过长
|
||||
if path.len() > MAX_PATHLEN as usize {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
let path = path.trim();
|
||||
|
||||
let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path);
|
||||
|
||||
@ -213,10 +207,7 @@ pub fn do_mkdir(path: &str, _mode: FileMode) -> Result<u64, SystemError> {
|
||||
|
||||
/// @brief 删除文件夹
|
||||
pub fn do_remove_dir(dirfd: i32, path: &str) -> Result<u64, SystemError> {
|
||||
// 文件名过长
|
||||
if path.len() > MAX_PATHLEN as usize {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
let path = path.trim();
|
||||
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?;
|
||||
@ -249,10 +240,8 @@ pub fn do_remove_dir(dirfd: i32, path: &str) -> Result<u64, SystemError> {
|
||||
|
||||
/// @brief 删除文件
|
||||
pub fn do_unlink_at(dirfd: i32, path: &str) -> Result<u64, SystemError> {
|
||||
// 文件名过长
|
||||
if path.len() > MAX_PATHLEN as usize {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
let path = path.trim();
|
||||
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?;
|
||||
let inode: Result<Arc<dyn IndexNode>, SystemError> =
|
||||
|
@ -36,10 +36,6 @@ pub(super) fn do_faccessat(
|
||||
|
||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
|
||||
if path.len() == 0 {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, &path)?;
|
||||
|
||||
// 如果找不到文件,则返回错误码ENOENT
|
||||
@ -52,10 +48,6 @@ pub(super) fn do_faccessat(
|
||||
pub fn do_fchmodat(dirfd: i32, path: *const u8, _mode: ModeType) -> Result<usize, SystemError> {
|
||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
|
||||
if path.len() == 0 {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, &path)?;
|
||||
|
||||
// 如果找不到文件,则返回错误码ENOENT
|
||||
@ -85,10 +77,8 @@ fn do_sys_openat2(
|
||||
follow_symlink: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
// kdebug!("open: path: {}, mode: {:?}", path, mode);
|
||||
// 文件名过长
|
||||
if path.len() > MAX_PATHLEN as usize {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
let path = path.trim();
|
||||
|
||||
let (inode_begin, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;
|
||||
let inode: Result<Arc<dyn IndexNode>, SystemError> = inode_begin.lookup_follow_symlink(
|
||||
&path,
|
||||
|
@ -1,21 +1,16 @@
|
||||
use core::ffi::CStr;
|
||||
use core::mem::size_of;
|
||||
|
||||
use alloc::{
|
||||
string::{String, ToString},
|
||||
sync::Arc,
|
||||
vec::Vec,
|
||||
};
|
||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
driver::base::{block::SeekFrom, device::device_number::DeviceNumber},
|
||||
filesystem::vfs::file::FileDescriptorVec,
|
||||
kerror,
|
||||
libs::rwlock::RwLockWriteGuard,
|
||||
mm::{verify_area, VirtAddr},
|
||||
process::ProcessManager,
|
||||
syscall::{
|
||||
user_access::{check_and_clone_cstr, UserBufferReader, UserBufferWriter},
|
||||
user_access::{check_and_clone_cstr, UserBufferWriter},
|
||||
Syscall,
|
||||
},
|
||||
time::TimeSpec,
|
||||
@ -86,6 +81,7 @@ bitflags! {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
/// # 文件信息结构体
|
||||
pub struct PosixKstat {
|
||||
/// 硬件设备ID
|
||||
@ -248,22 +244,34 @@ impl Syscall {
|
||||
///
|
||||
/// @return 文件描述符编号,或者是错误码
|
||||
pub fn open(
|
||||
path: &str,
|
||||
flags: FileMode,
|
||||
mode: ModeType,
|
||||
path: *const u8,
|
||||
o_flags: u32,
|
||||
mode: u32,
|
||||
follow_symlink: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
return do_sys_open(AtFlags::AT_FDCWD.bits(), path, flags, mode, follow_symlink);
|
||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
|
||||
let mode = ModeType::from_bits(mode as u32).ok_or(SystemError::EINVAL)?;
|
||||
return do_sys_open(
|
||||
AtFlags::AT_FDCWD.bits(),
|
||||
&path,
|
||||
open_flags,
|
||||
mode,
|
||||
follow_symlink,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn openat(
|
||||
dirfd: i32,
|
||||
path: &str,
|
||||
o_flags: FileMode,
|
||||
mode: ModeType,
|
||||
path: *const u8,
|
||||
o_flags: u32,
|
||||
mode: u32,
|
||||
follow_symlink: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
return do_sys_open(dirfd, path, o_flags, mode, follow_symlink);
|
||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
let open_flags: FileMode = FileMode::from_bits(o_flags).ok_or(SystemError::EINVAL)?;
|
||||
let mode = ModeType::from_bits(mode as u32).ok_or(SystemError::EINVAL)?;
|
||||
return do_sys_open(dirfd, &path, open_flags, mode, follow_symlink);
|
||||
}
|
||||
|
||||
/// @brief 关闭文件
|
||||
@ -351,7 +359,15 @@ impl Syscall {
|
||||
///
|
||||
/// @return Ok(usize) 调整后,文件访问指针相对于文件头部的偏移量
|
||||
/// @return Err(SystemError) 调整失败,返回posix错误码
|
||||
pub fn lseek(fd: i32, seek: SeekFrom) -> Result<usize, SystemError> {
|
||||
pub fn lseek(fd: i32, offset: i64, seek: u32) -> Result<usize, SystemError> {
|
||||
let seek = match seek {
|
||||
SEEK_SET => Ok(SeekFrom::SeekSet(offset)),
|
||||
SEEK_CUR => Ok(SeekFrom::SeekCurrent(offset)),
|
||||
SEEK_END => Ok(SeekFrom::SeekEnd(offset)),
|
||||
SEEK_MAX => Ok(SeekFrom::SeekEnd(0)),
|
||||
_ => Err(SystemError::EINVAL),
|
||||
}?;
|
||||
|
||||
let binding = ProcessManager::current_pcb().fd_table();
|
||||
let fd_table_guard = binding.read();
|
||||
let file = fd_table_guard
|
||||
@ -429,10 +445,14 @@ impl Syscall {
|
||||
/// EFAULT | 错误的地址
|
||||
///
|
||||
/// ENAMETOOLONG | 路径过长
|
||||
pub fn chdir(dest_path: &str) -> Result<usize, SystemError> {
|
||||
pub fn chdir(path: *const u8) -> Result<usize, SystemError> {
|
||||
if path.is_null() {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
|
||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
let proc = ProcessManager::current_pcb();
|
||||
// Copy path to kernel space to avoid some security issues
|
||||
let path = dest_path.to_string();
|
||||
let mut new_path = String::from("");
|
||||
if path.len() > 0 {
|
||||
let cwd = match path.as_bytes()[0] {
|
||||
@ -461,8 +481,7 @@ impl Syscall {
|
||||
}
|
||||
let inode =
|
||||
match ROOT_INODE().lookup_follow_symlink(&new_path, VFS_MAX_FOLLOW_SYMLINK_TIMES) {
|
||||
Err(e) => {
|
||||
kerror!("Change Directory Failed, Error = {:?}", e);
|
||||
Err(_) => {
|
||||
return Err(SystemError::ENOENT);
|
||||
}
|
||||
Ok(i) => i,
|
||||
@ -534,8 +553,9 @@ impl Syscall {
|
||||
/// @param path(r8) 路径 / mode(r9) 模式
|
||||
///
|
||||
/// @return uint64_t 负数错误码 / 0表示成功
|
||||
pub fn mkdir(path: &str, mode: usize) -> Result<usize, SystemError> {
|
||||
return do_mkdir(path, FileMode::from_bits_truncate(mode as u32)).map(|x| x as usize);
|
||||
pub fn mkdir(path: *const u8, mode: usize) -> Result<usize, SystemError> {
|
||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
return do_mkdir(&path, FileMode::from_bits_truncate(mode as u32)).map(|x| x as usize);
|
||||
}
|
||||
|
||||
/// **删除文件夹、取消文件的链接、删除文件的系统调用**
|
||||
@ -547,14 +567,15 @@ impl Syscall {
|
||||
/// - `flags`:标志位
|
||||
///
|
||||
///
|
||||
pub fn unlinkat(dirfd: i32, pathname: &str, flags: u32) -> Result<usize, SystemError> {
|
||||
pub fn unlinkat(dirfd: i32, path: *const u8, flags: u32) -> Result<usize, SystemError> {
|
||||
let flags = AtFlags::from_bits(flags as i32).ok_or(SystemError::EINVAL)?;
|
||||
|
||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
|
||||
if flags.contains(AtFlags::AT_REMOVEDIR) {
|
||||
// kdebug!("rmdir");
|
||||
match do_remove_dir(dirfd, &pathname) {
|
||||
match do_remove_dir(dirfd, &path) {
|
||||
Err(err) => {
|
||||
kerror!("Failed to Remove Directory, Error Code = {:?}", err);
|
||||
return Err(err);
|
||||
}
|
||||
Ok(_) => {
|
||||
@ -563,9 +584,8 @@ impl Syscall {
|
||||
}
|
||||
}
|
||||
|
||||
match do_unlink_at(dirfd, &pathname) {
|
||||
match do_unlink_at(dirfd, &path) {
|
||||
Err(err) => {
|
||||
kerror!("Failed to Remove Directory, Error Code = {:?}", err);
|
||||
return Err(err);
|
||||
}
|
||||
Ok(_) => {
|
||||
@ -574,32 +594,14 @@ impl Syscall {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rmdir(pathname: *const u8) -> Result<usize, SystemError> {
|
||||
let pathname: String = check_and_clone_cstr(pathname, Some(MAX_PATHLEN))?;
|
||||
if pathname.len() >= MAX_PATHLEN {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
let pathname = pathname.as_str().trim();
|
||||
return do_remove_dir(AtFlags::AT_FDCWD.bits(), pathname).map(|v| v as usize);
|
||||
pub fn rmdir(path: *const u8) -> Result<usize, SystemError> {
|
||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
return do_remove_dir(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize);
|
||||
}
|
||||
|
||||
pub fn unlink(pathname: *const u8) -> Result<usize, SystemError> {
|
||||
if pathname.is_null() {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
let ureader = UserBufferReader::new(pathname, MAX_PATHLEN, true)?;
|
||||
|
||||
let buf: &[u8] = ureader.buffer(0).unwrap();
|
||||
|
||||
let pathname: &CStr = CStr::from_bytes_until_nul(buf).map_err(|_| SystemError::EINVAL)?;
|
||||
|
||||
let pathname: &str = pathname.to_str().map_err(|_| SystemError::EINVAL)?;
|
||||
if pathname.len() >= MAX_PATHLEN {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
let pathname = pathname.trim();
|
||||
|
||||
return do_unlink_at(AtFlags::AT_FDCWD.bits(), pathname).map(|v| v as usize);
|
||||
pub fn unlink(path: *const u8) -> Result<usize, SystemError> {
|
||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
return do_unlink_at(AtFlags::AT_FDCWD.bits(), &path).map(|v| v as usize);
|
||||
}
|
||||
|
||||
/// # 修改文件名
|
||||
@ -892,45 +894,44 @@ impl Syscall {
|
||||
}
|
||||
|
||||
pub fn fstat(fd: i32, usr_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
|
||||
let mut writer = UserBufferWriter::new(usr_kstat, size_of::<PosixKstat>(), true)?;
|
||||
let kstat = Self::do_fstat(fd)?;
|
||||
if usr_kstat.is_null() {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
unsafe {
|
||||
*usr_kstat = kstat;
|
||||
}
|
||||
|
||||
writer.copy_one_to_user(&kstat, 0)?;
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub fn stat(path: &str, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
|
||||
let fd = Self::open(path, FileMode::O_RDONLY, ModeType::empty(), true)?;
|
||||
pub fn stat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
|
||||
let fd = Self::open(
|
||||
path,
|
||||
FileMode::O_RDONLY.bits(),
|
||||
ModeType::empty().bits(),
|
||||
true,
|
||||
)?;
|
||||
let r = Self::fstat(fd as i32, user_kstat);
|
||||
Self::close(fd).ok();
|
||||
return r;
|
||||
}
|
||||
|
||||
pub fn lstat(path: &str, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
|
||||
let fd = Self::open(path, FileMode::O_RDONLY, ModeType::empty(), false)?;
|
||||
pub fn lstat(path: *const u8, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
|
||||
let fd = Self::open(
|
||||
path,
|
||||
FileMode::O_RDONLY.bits(),
|
||||
ModeType::empty().bits(),
|
||||
false,
|
||||
)?;
|
||||
let r = Self::fstat(fd as i32, user_kstat);
|
||||
Self::close(fd).ok();
|
||||
return r;
|
||||
}
|
||||
|
||||
pub fn mknod(
|
||||
path_ptr: *const i8,
|
||||
path: *const u8,
|
||||
mode: ModeType,
|
||||
dev_t: DeviceNumber,
|
||||
) -> Result<usize, SystemError> {
|
||||
// 安全检验
|
||||
let len = unsafe { CStr::from_ptr(path_ptr).to_bytes().len() };
|
||||
let user_buffer = UserBufferReader::new(path_ptr, len, true)?;
|
||||
let buf = user_buffer.read_from_user::<u8>(0)?;
|
||||
let path = core::str::from_utf8(buf).map_err(|_| SystemError::EINVAL)?;
|
||||
|
||||
// 文件名过长
|
||||
if path.len() > MAX_PATHLEN as usize {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
let path = path.as_str().trim();
|
||||
|
||||
let inode: Result<Arc<dyn IndexNode>, SystemError> =
|
||||
ROOT_INODE().lookup_follow_symlink(path, VFS_MAX_FOLLOW_SYMLINK_TIMES);
|
||||
@ -980,12 +981,9 @@ impl Syscall {
|
||||
buf_size: usize,
|
||||
) -> Result<usize, SystemError> {
|
||||
let path = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
let path = path.as_str().trim();
|
||||
let mut user_buf = UserBufferWriter::new(user_buf, buf_size, true)?;
|
||||
|
||||
if path.len() == 0 {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, &path)?;
|
||||
|
||||
let inode = inode.lookup(path.as_str())?;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use core::{
|
||||
ffi::{c_char, c_int, c_void, CStr},
|
||||
ffi::{c_int, c_void},
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
|
||||
@ -22,14 +22,13 @@ use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::{cpu::cpu_reset, interrupt::TrapFrame, MMArch},
|
||||
driver::base::block::SeekFrom,
|
||||
filesystem::vfs::{
|
||||
fcntl::{AtFlags, FcntlCommand},
|
||||
file::FileMode,
|
||||
syscall::{ModeType, PosixKstat, SEEK_CUR, SEEK_END, SEEK_MAX, SEEK_SET},
|
||||
syscall::{ModeType, PosixKstat},
|
||||
MAX_PATHLEN,
|
||||
},
|
||||
include::bindings::bindings::{PAGE_2M_SIZE, PAGE_4K_SIZE},
|
||||
include::bindings::bindings::PAGE_4K_SIZE,
|
||||
kinfo,
|
||||
libs::align::page_align_up,
|
||||
mm::{verify_area, MemoryManagementArch, VirtAddr},
|
||||
@ -90,21 +89,11 @@ impl Syscall {
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_OPEN => {
|
||||
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() {
|
||||
Err(SystemError::EINVAL)
|
||||
} else {
|
||||
let path: &str = path.unwrap();
|
||||
let path = args[0] as *const u8;
|
||||
let flags = args[1] as u32;
|
||||
let mode = args[2] as u32;
|
||||
|
||||
let flags = args[1];
|
||||
let mode = args[2];
|
||||
|
||||
let open_flags: FileMode = FileMode::from_bits_truncate(flags as u32);
|
||||
let mode = ModeType::from_bits(mode as u32).ok_or(SystemError::EINVAL)?;
|
||||
Self::open(path, open_flags, mode, true)
|
||||
};
|
||||
res
|
||||
Self::open(path, flags, mode, true)
|
||||
}
|
||||
|
||||
SYS_RENAME => {
|
||||
@ -138,22 +127,11 @@ impl Syscall {
|
||||
|
||||
SYS_OPENAT => {
|
||||
let dirfd = args[0] as i32;
|
||||
let path: &CStr = unsafe { CStr::from_ptr(args[1] as *const c_char) };
|
||||
let flags = args[2];
|
||||
let mode = args[3];
|
||||
let path = args[1] as *const u8;
|
||||
let flags = args[2] as u32;
|
||||
let mode = args[3] as u32;
|
||||
|
||||
let path: Result<&str, core::str::Utf8Error> = path.to_str();
|
||||
let res = if path.is_err() {
|
||||
Err(SystemError::EINVAL)
|
||||
} else {
|
||||
let path: &str = path.unwrap();
|
||||
|
||||
let open_flags: FileMode =
|
||||
FileMode::from_bits(flags as u32).ok_or(SystemError::EINVAL)?;
|
||||
let mode = ModeType::from_bits(mode as u32).ok_or(SystemError::EINVAL)?;
|
||||
Self::openat(dirfd, path, open_flags, mode, true)
|
||||
};
|
||||
res
|
||||
Self::openat(dirfd, path, flags, mode, true)
|
||||
}
|
||||
SYS_CLOSE => {
|
||||
let fd = args[0];
|
||||
@ -187,15 +165,7 @@ impl Syscall {
|
||||
let offset = args[1] as i64;
|
||||
let whence = args[2] as u32;
|
||||
|
||||
let w = match whence {
|
||||
SEEK_SET => Ok(SeekFrom::SeekSet(offset)),
|
||||
SEEK_CUR => Ok(SeekFrom::SeekCurrent(offset)),
|
||||
SEEK_END => Ok(SeekFrom::SeekEnd(offset)),
|
||||
SEEK_MAX => Ok(SeekFrom::SeekEnd(0)),
|
||||
_ => Err(SystemError::EINVAL),
|
||||
}?;
|
||||
|
||||
Self::lseek(fd, w)
|
||||
Self::lseek(fd, offset, whence)
|
||||
}
|
||||
|
||||
SYS_PREAD64 => {
|
||||
@ -248,32 +218,7 @@ impl Syscall {
|
||||
SYS_REBOOT => Self::reboot(),
|
||||
|
||||
SYS_CHDIR => {
|
||||
// Closure for checking arguments
|
||||
let chdir_check = |arg0: usize| {
|
||||
if arg0 == 0 {
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
let path_ptr = arg0 as *const c_char;
|
||||
let virt_addr = VirtAddr::new(path_ptr as usize);
|
||||
// 权限校验
|
||||
if path_ptr.is_null()
|
||||
|| (frame.from_user()
|
||||
&& verify_area(virt_addr, PAGE_2M_SIZE as usize).is_err())
|
||||
{
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
let dest_path: &CStr = unsafe { CStr::from_ptr(path_ptr) };
|
||||
let dest_path: &str = dest_path.to_str().map_err(|_| SystemError::EINVAL)?;
|
||||
if dest_path.len() == 0 {
|
||||
return Err(SystemError::EINVAL);
|
||||
} else if dest_path.len() > MAX_PATHLEN as usize {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
|
||||
return Ok(dest_path);
|
||||
};
|
||||
|
||||
let r = chdir_check(args[0])?;
|
||||
let r = args[0] as *const u8;
|
||||
Self::chdir(r)
|
||||
}
|
||||
|
||||
@ -340,31 +285,10 @@ impl Syscall {
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_MKDIR => {
|
||||
let path_ptr = args[0] as *const c_char;
|
||||
let path = args[0] as *const u8;
|
||||
let mode = args[1];
|
||||
let virt_path_ptr = VirtAddr::new(path_ptr as usize);
|
||||
let security_check = || {
|
||||
if path_ptr.is_null()
|
||||
|| (frame.from_user()
|
||||
&& verify_area(virt_path_ptr, PAGE_2M_SIZE as usize).is_err())
|
||||
{
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
let path: &CStr = unsafe { CStr::from_ptr(path_ptr) };
|
||||
let path: &str = path.to_str().map_err(|_| SystemError::EINVAL)?.trim();
|
||||
|
||||
if path == "" {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
return Ok(path);
|
||||
};
|
||||
|
||||
let path = security_check();
|
||||
if path.is_err() {
|
||||
Err(path.unwrap_err())
|
||||
} else {
|
||||
Self::mkdir(path.unwrap(), mode)
|
||||
}
|
||||
Self::mkdir(path, mode)
|
||||
}
|
||||
|
||||
SYS_NANOSLEEP => {
|
||||
@ -407,43 +331,21 @@ impl Syscall {
|
||||
|
||||
SYS_UNLINKAT => {
|
||||
let dirfd = args[0] as i32;
|
||||
let pathname = args[1] as *const c_char;
|
||||
let path = args[1] as *const u8;
|
||||
let flags = args[2] as u32;
|
||||
let virt_pathname = VirtAddr::new(pathname as usize);
|
||||
if frame.from_user() && verify_area(virt_pathname, PAGE_4K_SIZE as usize).is_err() {
|
||||
Err(SystemError::EFAULT)
|
||||
} else if pathname.is_null() {
|
||||
Err(SystemError::EFAULT)
|
||||
} else {
|
||||
let get_path = || {
|
||||
let pathname: &CStr = unsafe { CStr::from_ptr(pathname) };
|
||||
|
||||
let pathname: &str = pathname.to_str().map_err(|_| SystemError::EINVAL)?;
|
||||
if pathname.len() >= MAX_PATHLEN {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
return Ok(pathname.trim());
|
||||
};
|
||||
let pathname = get_path();
|
||||
if pathname.is_err() {
|
||||
Err(pathname.unwrap_err())
|
||||
} else {
|
||||
// kdebug!("sys unlinkat: dirfd: {}, pathname: {}", dirfd, pathname.as_ref().unwrap());
|
||||
Self::unlinkat(dirfd, pathname.unwrap(), flags)
|
||||
}
|
||||
}
|
||||
Self::unlinkat(dirfd, path, flags)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_RMDIR => {
|
||||
let pathname = args[0] as *const u8;
|
||||
Self::rmdir(pathname)
|
||||
let path = args[0] as *const u8;
|
||||
Self::rmdir(path)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_UNLINK => {
|
||||
let pathname = args[0] as *const u8;
|
||||
Self::unlink(pathname)
|
||||
let path = args[0] as *const u8;
|
||||
Self::unlink(path)
|
||||
}
|
||||
SYS_KILL => {
|
||||
let pid = Pid::new(args[0]);
|
||||
@ -736,7 +638,7 @@ impl Syscall {
|
||||
let flags = args[1];
|
||||
let dev_t = args[2];
|
||||
let flags: ModeType = ModeType::from_bits_truncate(flags as u32);
|
||||
Self::mknod(path as *const i8, flags, DeviceNumber::from(dev_t as u32))
|
||||
Self::mknod(path as *const u8, flags, DeviceNumber::from(dev_t as u32))
|
||||
}
|
||||
|
||||
SYS_CLONE => {
|
||||
@ -788,40 +690,16 @@ impl Syscall {
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
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() {
|
||||
Err(SystemError::EINVAL)
|
||||
} else {
|
||||
let path: &str = path.unwrap();
|
||||
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::lstat(path, kstat),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
};
|
||||
|
||||
res
|
||||
let path = args[0] as *const u8;
|
||||
let kstat = args[1] as *mut PosixKstat;
|
||||
Self::lstat(path, kstat)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_STAT => {
|
||||
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() {
|
||||
Err(SystemError::EINVAL)
|
||||
} else {
|
||||
let path: &str = path.unwrap();
|
||||
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),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
};
|
||||
|
||||
res
|
||||
let path = args[0] as *const u8;
|
||||
let kstat = args[1] as *mut PosixKstat;
|
||||
Self::stat(path, kstat)
|
||||
}
|
||||
|
||||
SYS_EPOLL_CREATE => Self::epoll_create(args[0] as i32),
|
||||
@ -958,10 +836,10 @@ impl Syscall {
|
||||
|
||||
SYS_READLINKAT => {
|
||||
let dirfd = args[0] as i32;
|
||||
let pathname = args[1] as *const u8;
|
||||
let path = args[1] as *const u8;
|
||||
let buf = args[2] as *mut u8;
|
||||
let bufsiz = args[3];
|
||||
Self::readlink_at(dirfd, pathname, buf, bufsiz)
|
||||
Self::readlink_at(dirfd, path, buf, bufsiz)
|
||||
}
|
||||
|
||||
SYS_PRLIMIT64 => {
|
||||
|
@ -75,7 +75,7 @@ pub fn check_and_clone_cstr(
|
||||
max_length: Option<usize>,
|
||||
) -> Result<String, SystemError> {
|
||||
if user.is_null() {
|
||||
return Ok(String::new());
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
|
||||
// 从用户态读取,直到遇到空字符 '\0' 或者达到最大长度
|
||||
|
Loading…
x
Reference in New Issue
Block a user