From 6e9f00b5dbeabb4a05dd9a5df1ac2d9071b6e9e6 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Wed, 13 Mar 2019 18:00:07 +0800 Subject: [PATCH] fix process cwd. fix open path --- src/libos/src/fs/mod.rs | 26 ++++++++++++++++++-------- src/libos/src/process/mod.rs | 2 +- src/libos/src/process/process.rs | 10 +++++----- src/libos/src/process/spawn/mod.rs | 6 +++--- src/libos/src/syscall/mod.rs | 3 ++- test/readdir/main.c | 2 +- test/test_common.mk | 2 +- 7 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/libos/src/fs/mod.rs b/src/libos/src/fs/mod.rs index 2478dbbb..ced1aa9d 100644 --- a/src/libos/src/fs/mod.rs +++ b/src/libos/src/fs/mod.rs @@ -27,10 +27,13 @@ pub fn do_open(path: &str, flags: u32, mode: u32) -> Result { let flags = OpenFlags::from_bits_truncate(flags); info!("open: path: {:?}, flags: {:?}, mode: {:#o}", path, flags, mode); + let current_ref = process::get_current(); + let mut proc = current_ref.lock().unwrap(); + let inode = if flags.contains(OpenFlags::CREATE) { let (dir_path, file_name) = split_path(&path); - let dir_inode = ROOT_INODE.lookup(dir_path)?; + let dir_inode = proc.lookup_inode(dir_path)?; match dir_inode.find(file_name) { Ok(file_inode) => { if flags.contains(OpenFlags::EXCLUSIVE) { @@ -44,7 +47,7 @@ pub fn do_open(path: &str, flags: u32, mode: u32) -> Result { Err(e) => return Err(Error::from(e)), } } else { - ROOT_INODE.lookup(&path)? + proc.lookup_inode(&path)? }; let file_ref: Arc> = Arc::new(Box::new( @@ -52,10 +55,8 @@ pub fn do_open(path: &str, flags: u32, mode: u32) -> Result { )); let fd = { - let current_ref = process::get_current(); - let mut current = current_ref.lock().unwrap(); let close_on_spawn = flags.contains(OpenFlags::CLOEXEC); - current.get_files_mut().put(file_ref, close_on_spawn) + proc.get_files_mut().put(file_ref, close_on_spawn) }; Ok(fd) } @@ -245,9 +246,18 @@ extern "C" { impl Process { pub fn lookup_inode(&self, path: &str) -> Result, Error> { - let cwd = self.get_exec_path().split_at(1).1; // skip start '/' - let inode = ROOT_INODE.lookup(cwd)?.lookup(path)?; - Ok(inode) + debug!("lookup_inode: cwd: {:?}, path: {:?}", self.get_cwd(), path); + if path.len() > 0 && path.as_bytes()[0] == b'/' { + // absolute path + let abs_path = path.trim_start_matches('/'); + let inode = ROOT_INODE.lookup(abs_path)?; + Ok(inode) + } else { + // relative path + let cwd = self.get_cwd().trim_start_matches('/'); + let inode = ROOT_INODE.lookup(cwd)?.lookup(path)?; + Ok(inode) + } } } diff --git a/src/libos/src/process/mod.rs b/src/libos/src/process/mod.rs index 058e7d8d..4d5315aa 100644 --- a/src/libos/src/process/mod.rs +++ b/src/libos/src/process/mod.rs @@ -18,7 +18,7 @@ pub struct Process { pgid: pid_t, tgid: pid_t, exit_status: i32, - exec_path: String, + cwd: String, parent: Option, children: Vec, waiting_children: Option>, diff --git a/src/libos/src/process/process.rs b/src/libos/src/process/process.rs index e583f77a..1d99404f 100644 --- a/src/libos/src/process/process.rs +++ b/src/libos/src/process/process.rs @@ -13,7 +13,7 @@ lazy_static! { pgid: 0, tgid: 0, exit_status: 0, - exec_path: "".to_owned(), + cwd: "/".to_owned(), parent: None, children: Vec::new(), waiting_children: Default::default(), @@ -25,7 +25,7 @@ lazy_static! { impl Process { pub fn new( - exec_path: &str, + cwd: &str, task: Task, vm: ProcessVM, file_table: FileTable, @@ -37,7 +37,7 @@ impl Process { pid: new_pid, pgid: new_pid, tgid: new_pid, - exec_path: exec_path.to_owned(), + cwd: cwd.to_owned(), exit_status: 0, parent: None, children: Vec::new(), @@ -69,8 +69,8 @@ impl Process { pub fn get_exit_status(&self) -> i32 { self.exit_status } - pub fn get_exec_path(&self) -> &str { - &self.exec_path + pub fn get_cwd(&self) -> &str { + &self.cwd } pub fn get_vm(&self) -> &ProcessVM { &self.vm diff --git a/src/libos/src/process/spawn/mod.rs b/src/libos/src/process/spawn/mod.rs index 4ce641fa..7e44de14 100644 --- a/src/libos/src/process/spawn/mod.rs +++ b/src/libos/src/process/spawn/mod.rs @@ -30,7 +30,7 @@ pub fn do_spawn>( parent_ref: &ProcessRef, ) -> Result { let mut elf_buf = { - let path = elf_path.as_ref().to_str().unwrap(); + let path = elf_path.as_ref().to_str().unwrap().trim_start_matches('/'); let inode = ROOT_INODE.lookup(path)?; inode.read_as_vec()? }; @@ -62,8 +62,8 @@ pub fn do_spawn>( init_task(program_entry, stack_top, argv, envp)? }; let files = init_files(parent_ref, file_actions)?; - let exec_path = elf_path.as_ref().to_str().unwrap(); - Process::new(exec_path, task, vm, files)? + let cwd = elf_path.as_ref().parent().unwrap().to_str().unwrap(); + Process::new(cwd, task, vm, files)? }; parent_adopts_new_child(&parent_ref, &new_process_ref); process_table::put(new_pid, new_process_ref.clone()); diff --git a/src/libos/src/syscall/mod.rs b/src/libos/src/syscall/mod.rs index 854894d1..62eeabed 100644 --- a/src/libos/src/syscall/mod.rs +++ b/src/libos/src/syscall/mod.rs @@ -84,6 +84,7 @@ pub extern "C" fn dispatch_syscall( _ => do_unknown(num), }; + debug!("syscall return: {:?}", ret); match ret { Ok(code) => code as isize, @@ -475,7 +476,7 @@ fn do_getcwd(buf: *mut u8, size: usize) -> Result { }; let proc_ref = process::get_current(); let mut proc = proc_ref.lock().unwrap(); - let cwd = proc.get_exec_path(); + let cwd = proc.get_cwd(); if cwd.len() + 1 > safe_buf.len() { return Err(Error::new(ERANGE, "buf is not long enough")); } diff --git a/test/readdir/main.c b/test/readdir/main.c index 26b8f46c..5e07cbfd 100644 --- a/test/readdir/main.c +++ b/test/readdir/main.c @@ -5,7 +5,7 @@ #include int main(int argc, const char* argv[]) { - DIR* dirp = opendir("."); + DIR* dirp = opendir("/"); if (dirp == NULL) { printf("failed to open directory at /\n"); return -1; diff --git a/test/test_common.mk b/test/test_common.mk index c0909b9e..6e969fdc 100644 --- a/test/test_common.mk +++ b/test/test_common.mk @@ -9,7 +9,7 @@ S_FILES := $(C_SRCS:%.c=%.S) C_OBJS := $(C_SRCS:%.c=%.o) FS_PATH := ../fs BIN_NAME := $(shell basename $(CUR_DIR)) -BIN_FS_PATH := $(BIN_NAME) +BIN_FS_PATH := /$(BIN_NAME) BIN_PATH := $(FS_PATH)/$(BIN_FS_PATH) OBJDUMP_FILE := bin.objdump READELF_FILE := bin.readelf