Skip to content

Commit 5c90a67

Browse files
committed
Fixes #124309. create_dir_all() operates iteratively instead of recursively.
1 parent 34a8c73 commit 5c90a67

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

library/std/src/fs.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3333,26 +3333,36 @@ impl DirBuilder {
33333333
return Ok(());
33343334
}
33353335

3336-
match self.inner.mkdir(path) {
3337-
Ok(()) => return Ok(()),
3338-
Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
3339-
Err(_) if path.is_dir() => return Ok(()),
3336+
let mut uncreated_dirs = Vec::new();
3337+
let mut current = path;
3338+
3339+
while match self.inner.mkdir(current) {
3340+
Ok(()) => false,
3341+
Err(e) if e.kind() == io::ErrorKind::NotFound => true,
3342+
// we check if the err is AlreadyExists for two reasons
3343+
// - in case the path exists as a *file*
3344+
// - and to avoid calls to .is_dir() in case of other errs
3345+
// (i.e. PermissionDenied)
3346+
Err(e) if e.kind() == io::ErrorKind::AlreadyExists && current.is_dir() => false,
33403347
Err(e) => return Err(e),
3341-
}
3342-
match path.parent() {
3343-
Some(p) => self.create_dir_all(p)?,
3344-
None => {
3345-
return Err(io::const_error!(
3346-
io::ErrorKind::Uncategorized,
3347-
"failed to create whole tree",
3348-
));
3348+
} && let Some(parent) = current.parent()
3349+
{
3350+
if parent == Path::new("") {
3351+
break;
33493352
}
3353+
uncreated_dirs.push(current);
3354+
current = parent;
33503355
}
3351-
match self.inner.mkdir(path) {
3352-
Ok(()) => Ok(()),
3353-
Err(_) if path.is_dir() => Ok(()),
3354-
Err(e) => Err(e),
3356+
3357+
for uncreated_dir in uncreated_dirs.iter().rev() {
3358+
if let Err(e) = self.inner.mkdir(uncreated_dir) {
3359+
if !uncreated_dir.is_dir() {
3360+
return Err(e);
3361+
}
3362+
}
33553363
}
3364+
3365+
Ok(())
33563366
}
33573367
}
33583368

0 commit comments

Comments
 (0)