Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 27 additions & 17 deletions library/std/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3333,26 +3333,36 @@ impl DirBuilder {
return Ok(());
}

match self.inner.mkdir(path) {
Ok(()) => return Ok(()),
Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
Err(_) if path.is_dir() => return Ok(()),
Err(e) => return Err(e),
}
match path.parent() {
Some(p) => self.create_dir_all(p)?,
None => {
return Err(io::const_error!(
io::ErrorKind::Uncategorized,
"failed to create whole tree",
));
let ancestors = path.ancestors();
let mut uncreated_dir_ctr = 0;

for ancestor in ancestors {
if ancestor == Path::new("") {
break;
}

match self.inner.mkdir(ancestor) {
Ok(()) => break,
Err(e) if e.kind() == io::ErrorKind::NotFound => uncreated_dir_ctr += 1,
// we check if the err is AlreadyExists for two reasons
// - in case the path exists as a *file*
// - and to avoid calls to .is_dir() in case of other errs
// (i.e. PermissionDenied)
Err(e) if e.kind() == io::ErrorKind::AlreadyExists && ancestor.is_dir() => break,
Err(e) => return Err(e),
}
}
match self.inner.mkdir(path) {
Ok(()) => Ok(()),
Err(_) if path.is_dir() => Ok(()),
Err(e) => Err(e),

let uncreated_dirs: Box<[_]> = ancestors.take(uncreated_dir_ctr).collect();
for uncreated_dir in uncreated_dirs.iter().rev() {
if let Err(e) = self.inner.mkdir(uncreated_dir) {
if !uncreated_dir.is_dir() {
return Err(e);
}
}
}

Ok(())
}
}

Expand Down