mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-10 08:06:48 +00:00
完善pipe系统调用以及openat系统调用 (#441)
This commit is contained in:
parent
bf4a48994a
commit
0fb515b011
@ -23,6 +23,7 @@ pub const SYS_FCHMOD: usize = 91;
|
||||
pub const SYS_UMASK: usize = 95;
|
||||
pub const SYS_SYSINFO: usize = 99;
|
||||
pub const SYS_CLOCK_GETTIME: usize = 228;
|
||||
pub const SYS_OPENAT: usize = 257;
|
||||
pub const SYS_FCHMODAT: usize = 268;
|
||||
pub const SYS_FACCESSAT: usize = 269;
|
||||
pub const SYS_PRLIMIT64: usize = 302;
|
||||
|
@ -218,7 +218,7 @@ pub fn do_remove_dir(dirfd: i32, path: &str) -> Result<u64, SystemError> {
|
||||
}
|
||||
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path.to_string())?;
|
||||
let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?;
|
||||
|
||||
let inode: Result<Arc<dyn IndexNode>, SystemError> =
|
||||
inode_begin.lookup_follow_symlink(remain_path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES);
|
||||
@ -258,7 +258,7 @@ pub fn do_unlink_at(dirfd: i32, path: &str) -> Result<u64, SystemError> {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path.to_string())?;
|
||||
let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?;
|
||||
|
||||
let inode: Result<Arc<dyn IndexNode>, SystemError> =
|
||||
inode_begin.lookup_follow_symlink(&remain_path, VFS_MAX_FOLLOW_SYMLINK_TIMES);
|
||||
|
@ -46,45 +46,49 @@ bitflags! {
|
||||
/// 与Linux 5.19.10的uapi/asm-generic/fcntl.h相同
|
||||
/// https://opengrok.ringotek.cn/xref/linux-5.19.10/tools/include/uapi/asm-generic/fcntl.h#19
|
||||
pub struct FileMode: u32{
|
||||
/* File access modes for `open' and `fcntl'. */
|
||||
/// Open Read-only
|
||||
const O_RDONLY = 0o0;
|
||||
/// Open Write-only
|
||||
const O_WRONLY = 0o1;
|
||||
/// Open read/write
|
||||
const O_RDWR = 0o2;
|
||||
/// Mask for file access modes
|
||||
const O_ACCMODE = 0o00000003;
|
||||
/* File access modes for `open' and `fcntl'. */
|
||||
/// Open Read-only
|
||||
const O_RDONLY = 0o0;
|
||||
/// Open Write-only
|
||||
const O_WRONLY = 0o1;
|
||||
/// Open read/write
|
||||
const O_RDWR = 0o2;
|
||||
/// Mask for file access modes
|
||||
const O_ACCMODE = 0o00000003;
|
||||
|
||||
/* Bits OR'd into the second argument to open. */
|
||||
/// Create file if it does not exist
|
||||
const O_CREAT = 0o00000100;
|
||||
/// Fail if file already exists
|
||||
const O_EXCL = 0o00000200;
|
||||
/// Do not assign controlling terminal
|
||||
const O_NOCTTY = 0o00000400;
|
||||
/// 文件存在且是普通文件,并以O_RDWR或O_WRONLY打开,则它会被清空
|
||||
const O_TRUNC = 0o00001000;
|
||||
/// 文件指针会被移动到文件末尾
|
||||
const O_APPEND = 0o00002000;
|
||||
/// 非阻塞式IO模式
|
||||
const O_NONBLOCK = 0o00004000;
|
||||
/// 每次write都等待物理I/O完成,但是如果写操作不影响读取刚写入的数据,则不等待文件属性更新
|
||||
const O_DSYNC = 0o00010000;
|
||||
/// fcntl, for BSD compatibility
|
||||
const FASYNC = 0o00020000;
|
||||
/* direct disk access hint */
|
||||
const O_DIRECT = 0o00040000;
|
||||
const O_LARGEFILE = 0o00100000;
|
||||
/// 打开的必须是一个目录
|
||||
const O_DIRECTORY = 0o00200000;
|
||||
/// Do not follow symbolic links
|
||||
const O_NOFOLLOW = 0o00400000;
|
||||
const O_NOATIME = 0o01000000;
|
||||
/// set close_on_exec
|
||||
const O_CLOEXEC = 0o02000000;
|
||||
/// 每次write都等到物理I/O完成,包括write引起的文件属性的更新
|
||||
const O_SYNC = 0o04000000;
|
||||
/* Bits OR'd into the second argument to open. */
|
||||
/// Create file if it does not exist
|
||||
const O_CREAT = 0o00000100;
|
||||
/// Fail if file already exists
|
||||
const O_EXCL = 0o00000200;
|
||||
/// Do not assign controlling terminal
|
||||
const O_NOCTTY = 0o00000400;
|
||||
/// 文件存在且是普通文件,并以O_RDWR或O_WRONLY打开,则它会被清空
|
||||
const O_TRUNC = 0o00001000;
|
||||
/// 文件指针会被移动到文件末尾
|
||||
const O_APPEND = 0o00002000;
|
||||
/// 非阻塞式IO模式
|
||||
const O_NONBLOCK = 0o00004000;
|
||||
/// 每次write都等待物理I/O完成,但是如果写操作不影响读取刚写入的数据,则不等待文件属性更新
|
||||
const O_DSYNC = 0o00010000;
|
||||
/// fcntl, for BSD compatibility
|
||||
const FASYNC = 0o00020000;
|
||||
/* direct disk access hint */
|
||||
const O_DIRECT = 0o00040000;
|
||||
const O_LARGEFILE = 0o00100000;
|
||||
/// 打开的必须是一个目录
|
||||
const O_DIRECTORY = 0o00200000;
|
||||
/// Do not follow symbolic links
|
||||
const O_NOFOLLOW = 0o00400000;
|
||||
const O_NOATIME = 0o01000000;
|
||||
/// set close_on_exec
|
||||
const O_CLOEXEC = 0o02000000;
|
||||
/// 每次write都等到物理I/O完成,包括write引起的文件属性的更新
|
||||
const O_SYNC = 0o04000000;
|
||||
|
||||
const O_PATH = 0o10000000;
|
||||
|
||||
const O_PATH_FLAGS = Self::O_DIRECTORY.bits|Self::O_NOFOLLOW.bits|Self::O_CLOEXEC.bits|Self::O_PATH.bits;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,17 @@
|
||||
use alloc::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
driver::base::block::SeekFrom,
|
||||
process::ProcessManager,
|
||||
syscall::{user_access::check_and_clone_cstr, SystemError},
|
||||
};
|
||||
|
||||
use super::{
|
||||
fcntl::AtFlags, syscall::ModeType, utils::user_path_at, MAX_PATHLEN,
|
||||
VFS_MAX_FOLLOW_SYMLINK_TIMES,
|
||||
fcntl::AtFlags,
|
||||
file::{File, FileMode},
|
||||
syscall::{ModeType, OpenHow, OpenHowResolve},
|
||||
utils::{rsplit_path, user_path_at},
|
||||
FileType, IndexNode, MAX_PATHLEN, ROOT_INODE, VFS_MAX_FOLLOW_SYMLINK_TIMES,
|
||||
};
|
||||
|
||||
pub(super) fn do_faccessat(
|
||||
@ -34,7 +40,7 @@ pub(super) fn do_faccessat(
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;
|
||||
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, &path)?;
|
||||
|
||||
// 如果找不到文件,则返回错误码ENOENT
|
||||
let _inode = inode.lookup_follow_symlink(path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
|
||||
@ -50,7 +56,7 @@ pub fn do_fchmodat(dirfd: i32, path: *const u8, _mode: ModeType) -> Result<usize
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;
|
||||
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, &path)?;
|
||||
|
||||
// 如果找不到文件,则返回错误码ENOENT
|
||||
let _inode = inode.lookup_follow_symlink(path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
|
||||
@ -60,3 +66,93 @@ pub fn do_fchmodat(dirfd: i32, path: *const u8, _mode: ModeType) -> Result<usize
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
pub(super) fn do_sys_open(
|
||||
dfd: i32,
|
||||
path: &str,
|
||||
o_flags: FileMode,
|
||||
mode: ModeType,
|
||||
follow_symlink: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
let how = OpenHow::new(o_flags, mode, OpenHowResolve::empty());
|
||||
return do_sys_openat2(dfd, path, how, follow_symlink);
|
||||
}
|
||||
|
||||
fn do_sys_openat2(
|
||||
dirfd: i32,
|
||||
path: &str,
|
||||
how: OpenHow,
|
||||
follow_symlink: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
// kdebug!("open: path: {}, mode: {:?}", path, mode);
|
||||
// 文件名过长
|
||||
if path.len() > MAX_PATHLEN as usize {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
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,
|
||||
if follow_symlink {
|
||||
VFS_MAX_FOLLOW_SYMLINK_TIMES
|
||||
} else {
|
||||
0
|
||||
},
|
||||
);
|
||||
|
||||
let inode: Arc<dyn IndexNode> = if inode.is_err() {
|
||||
let errno = inode.unwrap_err();
|
||||
// 文件不存在,且需要创建
|
||||
if how.o_flags.contains(FileMode::O_CREAT)
|
||||
&& !how.o_flags.contains(FileMode::O_DIRECTORY)
|
||||
&& errno == SystemError::ENOENT
|
||||
{
|
||||
let (filename, parent_path) = rsplit_path(&path);
|
||||
// 查找父目录
|
||||
let parent_inode: Arc<dyn IndexNode> =
|
||||
ROOT_INODE().lookup(parent_path.unwrap_or("/"))?;
|
||||
// 创建文件
|
||||
let inode: Arc<dyn IndexNode> = parent_inode.create(
|
||||
filename,
|
||||
FileType::File,
|
||||
ModeType::from_bits_truncate(0o755),
|
||||
)?;
|
||||
inode
|
||||
} else {
|
||||
// 不需要创建文件,因此返回错误码
|
||||
return Err(errno);
|
||||
}
|
||||
} else {
|
||||
inode.unwrap()
|
||||
};
|
||||
|
||||
let file_type: FileType = inode.metadata()?.file_type;
|
||||
// 如果要打开的是文件夹,而目标不是文件夹
|
||||
if how.o_flags.contains(FileMode::O_DIRECTORY) && file_type != FileType::Dir {
|
||||
return Err(SystemError::ENOTDIR);
|
||||
}
|
||||
|
||||
// 创建文件对象
|
||||
|
||||
let mut file: File = File::new(inode, how.o_flags)?;
|
||||
|
||||
// 打开模式为“追加”
|
||||
if how.o_flags.contains(FileMode::O_APPEND) {
|
||||
file.lseek(SeekFrom::SeekEnd(0))?;
|
||||
}
|
||||
|
||||
// 如果O_TRUNC,并且,打开模式包含O_RDWR或O_WRONLY,清空文件
|
||||
if how.o_flags.contains(FileMode::O_TRUNC)
|
||||
&& (how.o_flags.contains(FileMode::O_RDWR) || how.o_flags.contains(FileMode::O_WRONLY))
|
||||
&& file_type == FileType::File
|
||||
{
|
||||
file.ftruncate(0)?;
|
||||
}
|
||||
// 把文件对象存入pcb
|
||||
let r = ProcessManager::current_pcb()
|
||||
.fd_table()
|
||||
.write()
|
||||
.alloc_fd(file, None)
|
||||
.map(|fd| fd as usize);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ use super::{
|
||||
core::{do_mkdir, do_remove_dir, do_unlink_at},
|
||||
fcntl::{AtFlags, FcntlCommand, FD_CLOEXEC},
|
||||
file::{File, FileMode},
|
||||
open::{do_faccessat, do_fchmodat},
|
||||
open::{do_faccessat, do_fchmodat, do_sys_open},
|
||||
utils::{rsplit_path, user_path_at},
|
||||
Dirent, FileType, IndexNode, MAX_PATHLEN, ROOT_INODE, VFS_MAX_FOLLOW_SYMLINK_TIMES,
|
||||
};
|
||||
@ -146,6 +146,100 @@ impl PosixKstat {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Arguments for how openat2(2) should open the target path. If only @flags and
|
||||
/// @mode are non-zero, then openat2(2) operates very similarly to openat(2).
|
||||
///
|
||||
/// However, unlike openat(2), unknown or invalid bits in @flags result in
|
||||
/// -EINVAL rather than being silently ignored. @mode must be zero unless one of
|
||||
/// {O_CREAT, O_TMPFILE} are set.
|
||||
///
|
||||
/// ## 成员变量
|
||||
///
|
||||
/// - flags: O_* flags.
|
||||
/// - mode: O_CREAT/O_TMPFILE file mode.
|
||||
/// - resolve: RESOLVE_* flags.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct PosixOpenHow {
|
||||
pub flags: u64,
|
||||
pub mode: u64,
|
||||
pub resolve: u64,
|
||||
}
|
||||
|
||||
impl PosixOpenHow {
|
||||
#[allow(dead_code)]
|
||||
pub fn new(flags: u64, mode: u64, resolve: u64) -> Self {
|
||||
Self {
|
||||
flags,
|
||||
mode,
|
||||
resolve,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct OpenHow {
|
||||
pub o_flags: FileMode,
|
||||
pub mode: ModeType,
|
||||
pub resolve: OpenHowResolve,
|
||||
}
|
||||
|
||||
impl OpenHow {
|
||||
pub fn new(mut o_flags: FileMode, mut mode: ModeType, resolve: OpenHowResolve) -> Self {
|
||||
if !o_flags.contains(FileMode::O_CREAT) {
|
||||
mode = ModeType::empty();
|
||||
}
|
||||
|
||||
if o_flags.contains(FileMode::O_PATH) {
|
||||
o_flags = o_flags.intersection(FileMode::O_PATH_FLAGS);
|
||||
}
|
||||
|
||||
Self {
|
||||
o_flags,
|
||||
mode,
|
||||
resolve,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PosixOpenHow> for OpenHow {
|
||||
fn from(posix_open_how: PosixOpenHow) -> Self {
|
||||
let o_flags = FileMode::from_bits_truncate(posix_open_how.flags as u32);
|
||||
let mode = ModeType::from_bits_truncate(posix_open_how.mode as u32);
|
||||
let resolve = OpenHowResolve::from_bits_truncate(posix_open_how.resolve as u64);
|
||||
return Self::new(o_flags, mode, resolve);
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct OpenHowResolve: u64{
|
||||
/// Block mount-point crossings
|
||||
/// (including bind-mounts).
|
||||
const RESOLVE_NO_XDEV = 0x01;
|
||||
|
||||
/// Block traversal through procfs-style
|
||||
/// "magic-links"
|
||||
const RESOLVE_NO_MAGICLINKS = 0x02;
|
||||
|
||||
/// Block traversal through all symlinks
|
||||
/// (implies OEXT_NO_MAGICLINKS)
|
||||
const RESOLVE_NO_SYMLINKS = 0x04;
|
||||
/// Block "lexical" trickery like
|
||||
/// "..", symlinks, and absolute
|
||||
const RESOLVE_BENEATH = 0x08;
|
||||
/// Make all jumps to "/" and ".."
|
||||
/// be scoped inside the dirfd
|
||||
/// (similar to chroot(2)).
|
||||
const RESOLVE_IN_ROOT = 0x10;
|
||||
// Only complete if resolution can be
|
||||
// completed through cached lookup. May
|
||||
// return -EAGAIN if that's not
|
||||
// possible.
|
||||
const RESOLVE_CACHED = 0x20;
|
||||
}
|
||||
}
|
||||
impl Syscall {
|
||||
/// @brief 为当前进程打开一个文件
|
||||
///
|
||||
@ -153,78 +247,23 @@ impl Syscall {
|
||||
/// @param o_flags 打开文件的标志位
|
||||
///
|
||||
/// @return 文件描述符编号,或者是错误码
|
||||
pub fn open(path: &str, mode: FileMode, follow_symlink: bool) -> Result<usize, SystemError> {
|
||||
// kdebug!("open: path: {}, mode: {:?}", path, mode);
|
||||
// 文件名过长
|
||||
if path.len() > MAX_PATHLEN as usize {
|
||||
return Err(SystemError::ENAMETOOLONG);
|
||||
}
|
||||
pub fn open(
|
||||
path: &str,
|
||||
flags: FileMode,
|
||||
mode: ModeType,
|
||||
follow_symlink: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
return do_sys_open(AtFlags::AT_FDCWD.bits(), path, flags, mode, follow_symlink);
|
||||
}
|
||||
|
||||
let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup_follow_symlink(
|
||||
path,
|
||||
if follow_symlink {
|
||||
VFS_MAX_FOLLOW_SYMLINK_TIMES
|
||||
} else {
|
||||
0
|
||||
},
|
||||
);
|
||||
|
||||
let inode: Arc<dyn IndexNode> = if inode.is_err() {
|
||||
let errno = inode.unwrap_err();
|
||||
// 文件不存在,且需要创建
|
||||
if mode.contains(FileMode::O_CREAT)
|
||||
&& !mode.contains(FileMode::O_DIRECTORY)
|
||||
&& errno == SystemError::ENOENT
|
||||
{
|
||||
let (filename, parent_path) = rsplit_path(path);
|
||||
// 查找父目录
|
||||
let parent_inode: Arc<dyn IndexNode> =
|
||||
ROOT_INODE().lookup(parent_path.unwrap_or("/"))?;
|
||||
// 创建文件
|
||||
let inode: Arc<dyn IndexNode> = parent_inode.create(
|
||||
filename,
|
||||
FileType::File,
|
||||
ModeType::from_bits_truncate(0o755),
|
||||
)?;
|
||||
inode
|
||||
} else {
|
||||
// 不需要创建文件,因此返回错误码
|
||||
return Err(errno);
|
||||
}
|
||||
} else {
|
||||
inode.unwrap()
|
||||
};
|
||||
|
||||
let file_type: FileType = inode.metadata()?.file_type;
|
||||
// 如果要打开的是文件夹,而目标不是文件夹
|
||||
if mode.contains(FileMode::O_DIRECTORY) && file_type != FileType::Dir {
|
||||
return Err(SystemError::ENOTDIR);
|
||||
}
|
||||
|
||||
// 创建文件对象
|
||||
|
||||
let mut file: File = File::new(inode, mode)?;
|
||||
|
||||
// 打开模式为“追加”
|
||||
if mode.contains(FileMode::O_APPEND) {
|
||||
file.lseek(SeekFrom::SeekEnd(0))?;
|
||||
}
|
||||
|
||||
// 如果O_TRUNC,并且,打开模式包含O_RDWR或O_WRONLY,清空文件
|
||||
if mode.contains(FileMode::O_TRUNC)
|
||||
&& (mode.contains(FileMode::O_RDWR) || mode.contains(FileMode::O_WRONLY))
|
||||
&& file_type == FileType::File
|
||||
{
|
||||
file.ftruncate(0)?;
|
||||
}
|
||||
// 把文件对象存入pcb
|
||||
let r = ProcessManager::current_pcb()
|
||||
.fd_table()
|
||||
.write()
|
||||
.alloc_fd(file, None)
|
||||
.map(|fd| fd as usize);
|
||||
|
||||
return r;
|
||||
pub fn openat(
|
||||
dirfd: i32,
|
||||
path: &str,
|
||||
o_flags: FileMode,
|
||||
mode: ModeType,
|
||||
follow_symlink: bool,
|
||||
) -> Result<usize, SystemError> {
|
||||
return do_sys_open(dirfd, path, o_flags, mode, follow_symlink);
|
||||
}
|
||||
|
||||
/// @brief 关闭文件
|
||||
@ -764,14 +803,14 @@ impl Syscall {
|
||||
}
|
||||
|
||||
pub fn stat(path: &str, user_kstat: *mut PosixKstat) -> Result<usize, SystemError> {
|
||||
let fd = Self::open(path, FileMode::O_RDONLY, true)?;
|
||||
let fd = Self::open(path, FileMode::O_RDONLY, ModeType::empty(), 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, false)?;
|
||||
let fd = Self::open(path, FileMode::O_RDONLY, ModeType::empty(), false)?;
|
||||
let r = Self::fstat(fd as i32, user_kstat);
|
||||
Self::close(fd).ok();
|
||||
return r;
|
||||
@ -847,7 +886,7 @@ impl Syscall {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, path)?;
|
||||
let (inode, path) = user_path_at(&ProcessManager::current_pcb(), dirfd, &path)?;
|
||||
|
||||
let inode = inode.lookup(path.as_str())?;
|
||||
if inode.metadata()?.file_type != FileType::SymLink {
|
||||
|
@ -35,9 +35,10 @@ pub fn rsplit_path(path: &str) -> (&str, Option<&str>) {
|
||||
pub fn user_path_at(
|
||||
pcb: &Arc<ProcessControlBlock>,
|
||||
dirfd: i32,
|
||||
mut path: String,
|
||||
path: &str,
|
||||
) -> Result<(Arc<dyn IndexNode>, String), SystemError> {
|
||||
let mut inode = ROOT_INODE();
|
||||
let ret_path;
|
||||
// 如果path不是绝对路径,则需要拼接
|
||||
if path.as_bytes()[0] != b'/' {
|
||||
// 如果dirfd不是AT_FDCWD,则需要检查dirfd是否是目录
|
||||
@ -58,13 +59,16 @@ pub fn user_path_at(
|
||||
}
|
||||
|
||||
inode = file_guard.inode();
|
||||
ret_path = String::from(path);
|
||||
} else {
|
||||
let mut cwd = pcb.basic().cwd();
|
||||
cwd.push('/');
|
||||
cwd.push_str(path.as_str());
|
||||
path = cwd;
|
||||
cwd.push_str(path);
|
||||
ret_path = cwd;
|
||||
}
|
||||
} else {
|
||||
ret_path = String::from(path);
|
||||
}
|
||||
|
||||
return Ok((inode, path));
|
||||
return Ok((inode, ret_path));
|
||||
}
|
||||
|
@ -6,7 +6,8 @@ use core::{
|
||||
use crate::{
|
||||
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,
|
||||
SYS_FCHMODAT, SYS_LSTAT, SYS_OPENAT, SYS_PRLIMIT64, SYS_READV, SYS_SYSINFO, SYS_UMASK,
|
||||
SYS_UNLINK,
|
||||
},
|
||||
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
||||
process::{
|
||||
@ -367,6 +368,7 @@ pub const SYS_RT_SIGRETURN: usize = 15;
|
||||
pub const SYS_IOCTL: usize = 16;
|
||||
|
||||
pub const SYS_WRITEV: usize = 20;
|
||||
pub const SYS_PIPE: usize = 22;
|
||||
|
||||
pub const SYS_MADVISE: usize = 28;
|
||||
|
||||
@ -456,7 +458,7 @@ pub const SYS_READLINK_AT: usize = 267;
|
||||
|
||||
pub const SYS_ACCEPT4: usize = 288;
|
||||
|
||||
pub const SYS_PIPE: usize = 293;
|
||||
pub const SYS_PIPE2: usize = 293;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub const SYS_GET_RANDOM: usize = 318;
|
||||
@ -515,8 +517,31 @@ impl Syscall {
|
||||
let path: &str = path.unwrap();
|
||||
|
||||
let flags = args[1];
|
||||
let mode = args[2];
|
||||
|
||||
let open_flags: FileMode = FileMode::from_bits_truncate(flags as u32);
|
||||
Self::open(path, open_flags, true)
|
||||
let mode = ModeType::from_bits(mode as u32).ok_or(SystemError::EINVAL)?;
|
||||
Self::open(path, open_flags, mode, true)
|
||||
};
|
||||
res
|
||||
}
|
||||
|
||||
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: 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
|
||||
}
|
||||
@ -725,6 +750,14 @@ impl Syscall {
|
||||
|
||||
SYS_CLOCK => Self::clock(),
|
||||
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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user