From 6fd531f820f063038e24dcd7baa1adaa2cbd469b Mon Sep 17 00:00:00 2001 From: Klimenty Tsoutsman Date: Wed, 6 Dec 2023 22:02:01 +1100 Subject: [PATCH] Handle paths with multiple components in `chdir` Adds support for changing multiple levels of directories at once e.g. `cd task/2`. Also since `components` normalizes the trailing slash, this fixes the bug which prevented changing into a directory followed by a trailing slash e.g. `cd namespaces/`. This is indicative of the larger issue that each `FsNode` implementation needs its own path parsing algorithm e.g. `cd task && cd ..` doesn't work because `TaskFs` doesn't support `..`. I'll have a PR ready soon to fix that issue. Signed-off-by: Klimenty Tsoutsman --- kernel/environment/src/lib.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/kernel/environment/src/lib.rs b/kernel/environment/src/lib.rs index df3e23d1dc..1dcf6f78d5 100644 --- a/kernel/environment/src/lib.rs +++ b/kernel/environment/src/lib.rs @@ -31,15 +31,17 @@ impl Environment { /// Changes the current working directory. #[doc(alias("change"))] pub fn chdir(&mut self, path: &Path) -> Result<()> { - let new_dir = self.working_dir.lock().get(path.as_ref()); - match new_dir { - Some(FileOrDir::Dir(dir_ref)) => { - self.working_dir = dir_ref; - Ok(()) + for component in path.components() { + let new = self.working_dir.lock().get(component.as_ref()); + match new { + Some(FileOrDir::Dir(dir)) => { + self.working_dir = dir; + } + Some(FileOrDir::File(_)) => return Err(Error::NotADirectory), + None => return Err(Error::NotFound), } - Some(FileOrDir::File(_)) => Err(Error::NotADirectory), - None => Err(Error::NotFound), } + Ok(()) } /// Returns the value of the environment variable with the given `key`.