about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2017-03-07 15:24:36 -0800
committerAlex Crichton <alex@alexcrichton.com>2017-03-07 15:24:36 -0800
commite412af2a887da25c987d4ca367b7b471b6c5fb55 (patch)
tree3dcb7d9de3e8c3a8bcef207ea4d8eac8b14e1596
parentb04ebef43242ade6be8968694caf56a0fb00a4d3 (diff)
downloadrust-e412af2a887da25c987d4ca367b7b471b6c5fb55.tar.gz
rust-e412af2a887da25c987d4ca367b7b471b6c5fb55.zip
rustbuild: Assert directory creation succeeds
I've been seeing failures on the bots when building jemalloc and my assumption
is that it's because cwd isn't created. That may be possible if this
`create_dir_all` call change in this commit fails, in which case we ignore the
error.

This commit updates the location to call `create_dir_racy` which handles
concurrent invocations, as multiple build scripts may be trying to create the
`native` dir.
-rw-r--r--src/build_helper/lib.rs25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs
index dffaebbd929..cb58a916fb7 100644
--- a/src/build_helper/lib.rs
+++ b/src/build_helper/lib.rs
@@ -12,10 +12,11 @@
 
 extern crate filetime;
 
-use std::{fs, env};
 use std::fs::File;
-use std::process::{Command, Stdio};
+use std::io;
 use std::path::{Path, PathBuf};
+use std::process::{Command, Stdio};
+use std::{fs, env};
 
 use filetime::FileTime;
 
@@ -196,7 +197,7 @@ pub fn native_lib_boilerplate(src_name: &str,
 
     let out_dir = env::var_os("RUSTBUILD_NATIVE_DIR").unwrap_or(env::var_os("OUT_DIR").unwrap());
     let out_dir = PathBuf::from(out_dir).join(out_name);
-    let _ = fs::create_dir_all(&out_dir);
+    t!(create_dir_racy(&out_dir));
     println!("cargo:rustc-link-lib=static={}", link_name);
     println!("cargo:rustc-link-search=native={}", out_dir.join(search_subdir).display());
 
@@ -223,3 +224,21 @@ fn fail(s: &str) -> ! {
     println!("\n\n{}\n\n", s);
     std::process::exit(1);
 }
+
+fn create_dir_racy(path: &Path) -> io::Result<()> {
+    match fs::create_dir(path) {
+        Ok(()) => return Ok(()),
+        Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => return Ok(()),
+        Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
+        Err(e) => return Err(e),
+    }
+    match path.parent() {
+        Some(p) => try!(create_dir_racy(p)),
+        None => return Err(io::Error::new(io::ErrorKind::Other, "failed to create whole tree")),
+    }
+    match fs::create_dir(path) {
+        Ok(()) => Ok(()),
+        Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => Ok(()),
+        Err(e) => Err(e),
+    }
+}