@@ -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