core/std: Fix race condition in os::mkdir_recursive tests

Added a change_dir_locked function to os, and use it in the
mkdir_recursive tests so that the tests don't clobber each other's
directory changes.
This commit is contained in:
Tim Chevalier 2013-04-30 17:58:24 -07:00
parent 9d966aef06
commit 782e06e0e3
2 changed files with 59 additions and 21 deletions

View file

@ -818,6 +818,36 @@ pub fn change_dir(p: &Path) -> bool {
}
}
/// Changes the current working directory to the specified
/// path while acquiring a global lock, then calls `action`.
/// If the change is successful, releases the lock and restores the
/// CWD to what it was before, returning true.
/// Returns false if the directory doesn't exist or if the directory change
/// is otherwise unsuccessful.
pub fn change_dir_locked(p: &Path, action: &fn()) -> bool {
use unstable::global::global_data_clone_create;
use unstable::{Exclusive, exclusive};
fn key(_: Exclusive<()>) { }
let result = unsafe {
global_data_clone_create(key, || {
~exclusive(())
})
};
do result.with_imm() |_| {
let old_dir = os::getcwd();
if change_dir(p) {
action();
change_dir(&old_dir)
}
else {
false
}
}
}
/// Copies a file from one location to another
pub fn copy_file(from: &Path, to: &Path) -> bool {
return do_copy_file(from, to);

View file

@ -42,13 +42,18 @@ mod tests {
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use core::os;
let root = mkdtemp(&os::tmpdir(), "temp").expect("recursive_mkdir_rel");
os::change_dir(&root);
let path = Path("frob");
assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
assert!(os::path_is_dir(&path));
assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
assert!(os::path_is_dir(&path));
let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel").
expect("recursive_mkdir_rel");
assert!(do os::change_dir_locked(&root) {
let path = Path("frob");
debug!("recursive_mkdir_rel: Making: %s in cwd %s [%?]", path.to_str(),
os::getcwd().to_str(),
os::path_exists(&path));
assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
assert!(os::path_is_dir(&path));
assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
assert!(os::path_is_dir(&path));
});
}
#[test]
@ -67,18 +72,21 @@ mod tests {
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use core::os;
let root = mkdtemp(&os::tmpdir(), "temp").expect("recursive_mkdir_rel_2");
os::change_dir(&root);
let path = Path("./frob/baz");
debug!("...Making: %s in cwd %s", path.to_str(), os::getcwd().to_str());
assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
assert!(os::path_is_dir(&path));
assert!(os::path_is_dir(&path.pop()));
let path2 = Path("quux/blat");
debug!("Making: %s in cwd %s", path2.to_str(), os::getcwd().to_str());
assert!(os::mkdir_recursive(&path2, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
assert!(os::path_is_dir(&path2));
assert!(os::path_is_dir(&path2.pop()));
let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel_2").
expect("recursive_mkdir_rel_2");
assert!(do os::change_dir_locked(&root) {
let path = Path("./frob/baz");
debug!("recursive_mkdir_rel_2: Making: %s in cwd %s [%?]", path.to_str(),
os::getcwd().to_str(), os::path_exists(&path));
assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
assert!(os::path_is_dir(&path));
assert!(os::path_is_dir(&path.pop()));
let path2 = Path("quux/blat");
debug!("recursive_mkdir_rel_2: Making: %s in cwd %s", path2.to_str(),
os::getcwd().to_str());
assert!(os::mkdir_recursive(&path2, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
assert!(os::path_is_dir(&path2));
assert!(os::path_is_dir(&path2.pop()));
});
}
}
}