diff --git a/.gitignore b/.gitignore index 4b4a5a8..021a507 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,8 @@ Cargo.lock # for eclipse .project +# for vscode .vscode + +# for vim +*.swp diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 274154c..7e52e7b 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -468,12 +468,34 @@ pub fn sys_chdir(path: *const u8) -> SysResult { return Err(SysError::ENOTDIR); } - if path.len() > 0 && path.as_bytes()[0] == b'/' { - // absolute - proc.cwd = path; - } else { - // relative - proc.cwd += &path; + // BUGFIX: '..' and '.' + if path.len() > 0 { + let cwd = match path.as_bytes()[0] { + b'/' => String::from("/"), + _ => proc.cwd.clone() + }; + let mut cwd_vec:Vec<_> = + cwd.split("/") + .filter(|&x| x != "") + .collect(); + let path_split = path.split("/").filter(|&x| x != ""); + for seg in path_split { + if seg == ".." { + cwd_vec.pop(); + } else if seg == "." { + // nothing to do here. + } else { + cwd_vec.push(seg); + } + } + proc.cwd = String::from(""); + for seg in cwd_vec { + proc.cwd.push_str("/"); + proc.cwd.push_str(seg); + } + if proc.cwd == "" { + proc.cwd = String::from("/"); + } } Ok(0) }