Skip to content

Commit 18f185b

Browse files
committed
unix: Provide _remove_dir_contents
The implementation is relatively straightforward. It's a shame that we need to reach for libc to get the error handling right! The return type is different to that of Windows's fs:_remove_dir_all. Unix does not need to canonicalize the path, so doesn't return a canonicalised path. This type difference is OK provided both versions typecheck at the call site, which will appear in a moment. Right now this code is not used - the caller will appear in the next commit - so we must temporarily add `#[allow]`. As discussed, and differently to my v1, https://github.com/XAMPPRocky/remove_dir_all/pull/22/files/30791c382ca9535d4fd9758e1b070393bfa6ef3e#diff-cff001b3dd9b58fd8acadc50ffc32f83 I have made remove_dir_contents intolerant of ENOENT. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
1 parent 90071cb commit 18f185b

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ num_cpus = "1.13"
2323
rayon = "1.4"
2424
winapi = {version = "0.3", features = ["std", "errhandlingapi", "winerror", "fileapi", "winbase"]}
2525

26+
[target.'cfg(not(windows))'.dependencies]
27+
libc = "0.2"
28+
2629
[dev-dependencies]
2730
doc-comment = "0.3"
2831
env_logger = "0.8.1"

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ doctest!("../README.md");
1919
#[cfg(windows)]
2020
mod fs;
2121

22+
#[cfg(not(windows))]
23+
mod unix;
24+
2225
#[cfg(windows)]
2326
pub use self::fs::remove_dir_all;
2427

src/unix.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#![allow(dead_code)]
2+
3+
use std::fs;
4+
use std::io;
5+
use std::path::Path;
6+
7+
fn remove_file_or_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
8+
match fs::remove_file(&path) {
9+
// Unfortunately, there is no ErrorKind for EISDIR
10+
Err(e) if e.raw_os_error() == Some(libc::EISDIR) =>
11+
fs::remove_dir_all(&path),
12+
r => r,
13+
}
14+
}
15+
16+
pub fn _remove_dir_contents<P: AsRef<Path>>(path: P) -> Result<(), io::Error> {
17+
for entry in fs::read_dir(path)? {
18+
let entry_path = entry?.path();
19+
remove_file_or_dir_all(&entry_path)?;
20+
}
21+
22+
Ok(())
23+
}

0 commit comments

Comments
 (0)