123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- use alloc::sync::Arc;
- use crate::{
- driver::base::block::SeekFrom,
- process::ProcessManager,
- syscall::{user_access::check_and_clone_cstr, SystemError},
- };
- use super::{
- 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(
- dirfd: i32,
- path: *const u8,
- mode: ModeType,
- flags: u32,
- ) -> Result<usize, SystemError> {
- if (mode.bits() & (!ModeType::S_IRWXO.bits())) != 0 {
- return Err(SystemError::EINVAL);
- }
- if (flags
- & (!((AtFlags::AT_EACCESS | AtFlags::AT_SYMLINK_NOFOLLOW | AtFlags::AT_EMPTY_PATH).bits()
- as u32)))
- != 0
- {
- return Err(SystemError::EINVAL);
- }
-
- 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)?;
-
- let _inode = inode.lookup_follow_symlink(path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
-
- return Ok(0);
- }
- 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)?;
-
- let _inode = inode.lookup_follow_symlink(path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
- kwarn!("do_fchmodat: not implemented yet\n");
-
- 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> {
-
-
- 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))?;
- }
-
- 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)?;
- }
-
- let r = ProcessManager::current_pcb()
- .fd_table()
- .write()
- .alloc_fd(file, None)
- .map(|fd| fd as usize);
- return r;
- }
|