From 694fb32a354ddb335ffad16fb457eb6091da6ea7 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Tue, 19 Mar 2019 23:44:18 +0800 Subject: [PATCH] add sys_chdir, sys_rename, sys_mkdir, sys_(un)link --- src/libos/src/fs/mod.rs | 68 ++++++++++++++++++++++++++++++++ src/libos/src/process/process.rs | 9 +++++ src/libos/src/syscall/mod.rs | 37 +++++++++++++++++ 3 files changed, 114 insertions(+) diff --git a/src/libos/src/fs/mod.rs b/src/libos/src/fs/mod.rs index d1450bda..8fe0777b 100644 --- a/src/libos/src/fs/mod.rs +++ b/src/libos/src/fs/mod.rs @@ -254,6 +254,74 @@ pub fn do_sync() -> Result<(), Error> { Ok(()) } +pub fn do_chdir(path: &str) -> Result<(), Error> { + let current_ref = process::get_current(); + let mut current_process = current_ref.lock().unwrap(); + let inode = current_process.lookup_inode(path)?; + let info = inode.metadata()?; + if info.type_ != FileType::Dir { + return Err(Error::new(ENOTDIR, "")); + } + current_process.change_cwd(path); + Ok(()) +} + +pub fn do_rename(oldpath: &str, newpath: &str) -> Result<(), Error> { + let current_ref = process::get_current(); + let current_process = current_ref.lock().unwrap(); + info!("rename: oldpath: {:?}, newpath: {:?}", oldpath, newpath); + + let (old_dir_path, old_file_name) = split_path(&oldpath); + let (new_dir_path, new_file_name) = split_path(&newpath); + let old_dir_inode = current_process.lookup_inode(old_dir_path)?; + let new_dir_inode = current_process.lookup_inode(new_dir_path)?; + // TODO: merge `rename` and `move` in VFS + if Arc::ptr_eq(&old_dir_inode, &new_dir_inode) { + old_dir_inode.rename(old_file_name, new_file_name)?; + } else { + old_dir_inode.move_(old_file_name, &new_dir_inode, new_file_name)?; + } + Ok(()) +} + +pub fn do_mkdir(path: &str, mode: usize) -> Result<(), Error> { + let current_ref = process::get_current(); + let current_process = current_ref.lock().unwrap(); + // TODO: check pathname + info!("mkdir: path: {:?}, mode: {:#o}", path, mode); + + let (dir_path, file_name) = split_path(&path); + let inode = current_process.lookup_inode(dir_path)?; + if inode.find(file_name).is_ok() { + return Err(Error::new(EEXIST, "")); + } + inode.create(file_name, FileType::Dir, mode as u32)?; + Ok(()) +} + +pub fn do_link(oldpath: &str, newpath: &str) -> Result<(), Error> { + let current_ref = process::get_current(); + let current_process = current_ref.lock().unwrap(); + info!("link: oldpath: {:?}, newpath: {:?}", oldpath, newpath); + + let (new_dir_path, new_file_name) = split_path(&newpath); + let inode = current_process.lookup_inode(&oldpath)?; + let new_dir_inode = current_process.lookup_inode(new_dir_path)?; + new_dir_inode.link(new_file_name, &inode)?; + Ok(()) +} + +pub fn do_unlink(path: &str) -> Result<(), Error> { + let current_ref = process::get_current(); + let current_process = current_ref.lock().unwrap(); + info!("unlink: path: {:?}", path); + + let (dir_path, file_name) = split_path(&path); + let dir_inode = current_process.lookup_inode(dir_path)?; + dir_inode.unlink(file_name)?; + Ok(()) +} + extern "C" { fn ocall_sync() -> sgx_status_t; } diff --git a/src/libos/src/process/process.rs b/src/libos/src/process/process.rs index 1d99404f..74afa537 100644 --- a/src/libos/src/process/process.rs +++ b/src/libos/src/process/process.rs @@ -90,6 +90,15 @@ impl Process { pub fn get_children(&self) -> &[ProcessWeakRef] { &self.children } + pub fn change_cwd(&mut self, path: &str) { + if path.len() > 0 && path.as_bytes()[0] == b'/' { + // absolute + self.cwd = path.to_owned(); + } else { + // relative + self.cwd += path; + } + } } impl Drop for Process { diff --git a/src/libos/src/syscall/mod.rs b/src/libos/src/syscall/mod.rs index 1de70a19..d0ae0340 100644 --- a/src/libos/src/syscall/mod.rs +++ b/src/libos/src/syscall/mod.rs @@ -49,6 +49,11 @@ pub extern "C" fn dispatch_syscall( SYS_GETDENTS64 => do_getdents64(arg0 as FileDesc, arg1 as *mut u8, arg2 as usize), SYS_SYNC => do_sync(), SYS_GETCWD => do_getcwd(arg0 as *mut u8, arg1 as usize), + SYS_CHDIR => do_chdir(arg0 as *mut i8), + SYS_RENAME => do_rename(arg0 as *const i8, arg1 as *const i8), + SYS_MKDIR => do_mkdir(arg0 as *const i8, arg1 as usize), + SYS_LINK => do_link(arg0 as *const i8, arg1 as *const i8), + SYS_UNLINK => do_unlink(arg0 as *const i8), SYS_EXIT => do_exit(arg0 as i32), SYS_SPAWN => do_spawn( @@ -505,3 +510,35 @@ fn do_getcwd(buf: *mut u8, size: usize) -> Result { safe_buf[cwd.len()] = 0; Ok(0) } + +fn do_chdir(path: *const i8) -> Result { + let path = clone_cstring_safely(path)?.to_string_lossy().into_owned(); + fs::do_chdir(&path)?; + Ok(0) +} + +fn do_rename(oldpath: *const i8, newpath: *const i8) -> Result { + let oldpath = clone_cstring_safely(oldpath)?.to_string_lossy().into_owned(); + let newpath = clone_cstring_safely(newpath)?.to_string_lossy().into_owned(); + fs::do_rename(&oldpath, &newpath)?; + Ok(0) +} + +fn do_mkdir(path: *const i8, mode: usize) -> Result { + let path = clone_cstring_safely(path)?.to_string_lossy().into_owned(); + fs::do_mkdir(&path, mode)?; + Ok(0) +} + +fn do_link(oldpath: *const i8, newpath: *const i8) -> Result { + let oldpath = clone_cstring_safely(oldpath)?.to_string_lossy().into_owned(); + let newpath = clone_cstring_safely(newpath)?.to_string_lossy().into_owned(); + fs::do_link(&oldpath, &newpath)?; + Ok(0) +} + +fn do_unlink(path: *const i8) -> Result { + let path = clone_cstring_safely(path)?.to_string_lossy().into_owned(); + fs::do_unlink(&path)?; + Ok(0) +}