about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorLaurent Bonnans <bonnans.l@gmail.com>2014-02-26 17:50:02 +0100
committerLaurent Bonnans <bonnans.l@gmail.com>2014-03-10 19:24:28 +0100
commit0fcd5d54552ec758f9e6c6f70071247fb13e117f (patch)
tree6eb3f6a27967ed85062087b9ef95abd5e0b66ae6 /src/libstd
parent62f1d68439dcfd509eaca29887afa97f22938373 (diff)
downloadrust-0fcd5d54552ec758f9e6c6f70071247fb13e117f.tar.gz
rust-0fcd5d54552ec758f9e6c6f70071247fb13e117f.zip
fs: use an iterative algorithm for 'mkdir_recursive'
as requested in #6109
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/io/fs.rs21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs
index 79e191a9ec9..3ad35e3124b 100644
--- a/src/libstd/io/fs.rs
+++ b/src/libstd/io/fs.rs
@@ -528,10 +528,25 @@ pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> {
     if path.is_dir() {
         return Ok(())
     }
-    if path.filename().is_some() {
-        try!(mkdir_recursive(&path.dir_path(), mode));
+
+    let mut comps = path.components();
+    let mut curpath = path.root_path().unwrap_or(Path::new("."));
+
+    for c in comps {
+        curpath.push(c);
+
+        match mkdir(&curpath, mode) {
+            Err(mkdir_err) => {
+                // already exists ?
+                if try!(stat(&curpath)).kind != io::TypeDirectory {
+                    return Err(mkdir_err);
+                }
+            }
+            Ok(()) => ()
+        }
     }
-    mkdir(path, mode)
+
+    Ok(())
 }
 
 /// Removes a directory at this path, after removing all its contents. Use