소스 검색

实现SYS_RMDIR (#566)

* 实现rmdir系统调用,整理do_remove_dir逻辑
Chenzx 1 년 전
부모
커밋
5eeefb8c80
4개의 변경된 파일23개의 추가작업 그리고 11개의 파일을 삭제
  1. 6 11
      kernel/src/filesystem/vfs/core.rs
  2. 9 0
      kernel/src/filesystem/vfs/syscall.rs
  3. 6 0
      kernel/src/syscall/mod.rs
  4. 2 0
      kernel/src/syscall/syscall_num.h

+ 6 - 11
kernel/src/filesystem/vfs/core.rs

@@ -220,19 +220,13 @@ 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)?;
+    let (filename, parent_path) = rsplit_path(&remain_path);
 
-    let inode: Result<Arc<dyn IndexNode>, SystemError> =
-        inode_begin.lookup_follow_symlink(remain_path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES);
-
-    if inode.is_err() {
-        let errno = inode.unwrap_err();
-        // 文件不存在
-        if errno == SystemError::ENOENT {
-            return Err(SystemError::ENOENT);
-        }
+    // 最后一项文件项为.时返回EINVAL
+    if filename == "." {
+        return Err(SystemError::EINVAL);
     }
 
-    let (filename, parent_path) = rsplit_path(&remain_path);
     // 查找父目录
     let parent_inode: Arc<dyn IndexNode> = inode_begin
         .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
@@ -241,7 +235,8 @@ pub fn do_remove_dir(dirfd: i32, path: &str) -> Result<u64, SystemError> {
         return Err(SystemError::ENOTDIR);
     }
 
-    let target_inode: Arc<dyn IndexNode> = parent_inode.find(filename)?;
+    // 在目标点为symlink时也返回ENOTDIR
+    let target_inode = parent_inode.find(filename)?;
     if target_inode.metadata()?.file_type != FileType::Dir {
         return Err(SystemError::ENOTDIR);
     }

+ 9 - 0
kernel/src/filesystem/vfs/syscall.rs

@@ -574,6 +574,15 @@ 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 unlink(pathname: *const u8) -> Result<usize, SystemError> {
         if pathname.is_null() {
             return Err(SystemError::EFAULT);

+ 6 - 0
kernel/src/syscall/mod.rs

@@ -408,6 +408,12 @@ impl Syscall {
                 }
             }
 
+            #[cfg(target_arch = "x86_64")]
+            SYS_RMDIR => {
+                let pathname = args[0] as *const u8;
+                Self::rmdir(pathname)
+            }
+
             #[cfg(target_arch = "x86_64")]
             SYS_UNLINK => {
                 let pathname = args[0] as *const u8;

+ 2 - 0
kernel/src/syscall/syscall_num.h

@@ -65,6 +65,8 @@
 
 #define SYS_MKDIR 83
 
+#define SYS_RMDIR 84
+
 #define SYS_GETTIMEOFDAY 96
 
 #define SYS_ARCH_PRCTL 158