Skip to content

Commit

Permalink
fs: implement remove_dir_all
Browse files Browse the repository at this point in the history
With this PR, the fs module is feature-complete and ready to be shipped.
  • Loading branch information
phip1611 committed May 12, 2023
1 parent 42e2013 commit 49f69a6
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 7 deletions.
5 changes: 4 additions & 1 deletion uefi-test-runner/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ pub fn test(sfs: ScopedProtocol<SimpleFileSystem>) -> Result<(), fs::Error> {
assert_eq!(boxinfo.file_size(), data_to_write.len() as u64);

// test remove dir all
// TODO
fs.remove_dir_all(cstr16!("foo_dir\\1"))?;
// file should not be available after remove all
let err = fs.try_exists(cstr16!("foo_dir\\1"));
assert!(err.is_err());

Ok(())
}
3 changes: 3 additions & 0 deletions uefi/src/fs/dir_entry_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ use alloc::boxed::Box;

/// Iterates over the entries of an UEFI directory. It returns boxed values of
/// type [`UefiFileInfo`].
///
/// Note that on UEFI/FAT-style file systems, the root dir usually doesn't
/// return the entries `.` and `..`, whereas sub directories do.
#[derive(Debug)]
pub struct UefiDirectoryIter(UefiDirectoryHandle);

Expand Down
38 changes: 32 additions & 6 deletions uefi/src/fs/file_system/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use core::fmt;
use core::fmt::{Debug, Formatter};
use core::ops::Deref;
use log::debug;
use uefi::CStr16;
use uefi_macros::cstr16;

/// Return type for public [`FileSystem`] operations.
pub type FileSystemResult<T> = Result<T, Error>;
Expand Down Expand Up @@ -181,11 +183,35 @@ impl<'a> FileSystem<'a> {
}
}

/*/// Removes a directory at this path, after removing all its contents. Use
/// Removes a directory at this path, after removing all its contents. Use
/// carefully!
pub fn remove_dir_all(&mut self, path: impl AsRef<Path>) -> FileSystemResult<()> {
const SKIP_DIRS: [&CStr16; 2] = [cstr16!("."), cstr16!("..")];
let path = path.as_ref();
}*/
for file_info in self
.read_dir(path)?
.filter_map(|file_info_result| file_info_result.ok())
{
if SKIP_DIRS.contains(&file_info.file_name()) {
continue;
}

let mut abs_entry_path = PathBuf::new();
abs_entry_path.push(path);
abs_entry_path.push(file_info.file_name());
if file_info.is_directory() {
// delete all inner files
// This recursion is fine as there are no links in UEFI/FAT file
// systems. No cycles possible.
self.remove_dir_all(&abs_entry_path)?;
} else {
self.remove_file(abs_entry_path)?;
}
}
// Now that the dir is empty, we delete it as final step.
self.remove_dir(path)?;
Ok(())
}

/// Removes a file from the filesystem.
pub fn remove_file(&mut self, path: impl AsRef<Path>) -> FileSystemResult<()> {
Expand Down Expand Up @@ -282,17 +308,17 @@ impl<'a> FileSystem<'a> {
/// absolute path.
///
/// May create a file if [`UefiFileMode::CreateReadWrite`] is set. May
/// create a directory if [`UefiFileMode::CreateReadWrite`] and `is_dir`
/// is set.
/// create a directory if [`UefiFileMode::CreateReadWrite`] and `create_dir`
/// is set. The parameter `create_dir` is ignored otherwise.
fn open(
&mut self,
path: &Path,
mode: UefiFileMode,
is_dir: bool,
create_dir: bool,
) -> FileSystemResult<UefiFileHandle> {
validate_path(path)?;

let attr = if mode == UefiFileMode::CreateReadWrite && is_dir {
let attr = if mode == UefiFileMode::CreateReadWrite && create_dir {
UefiFileAttribute::DIRECTORY
} else {
UefiFileAttribute::empty()
Expand Down

0 comments on commit 49f69a6

Please sign in to comment.