add and use rename_or_copy_remove fn that fallback to copy & remove

This commit is contained in:
king6cong 2017-02-03 17:42:01 +08:00
parent 5e41ec2ccc
commit 768f6a9b57
2 changed files with 27 additions and 1 deletions

View File

@ -82,6 +82,31 @@ pub fn link_or_copy<P: AsRef<Path>, Q: AsRef<Path>>(p: P, q: Q) -> io::Result<Li
}
}
#[derive(Debug)]
pub enum RenameOrCopyRemove {
Rename,
CopyRemove
}
/// Rename `p` into `q`, preferring to use `rename` if possible.
/// If `rename` fails (rename may fail for reasons such as crossing filesystem), fallback to copy & remove
pub fn rename_or_copy_remove<P: AsRef<Path>, Q: AsRef<Path>>(p: P, q: Q) -> io::Result<RenameOrCopyRemove> {
let p = p.as_ref();
let q = q.as_ref();
match fs::rename(p, q) {
Ok(()) => Ok(RenameOrCopyRemove::Rename),
Err(_) => {
match fs::copy(p, q) {
Ok(_) => {
fs::remove_file(p)?;
Ok(RenameOrCopyRemove::CopyRemove)
},
Err(e) => Err(e)
}
}
}
}
// Like std::fs::create_dir_all, except handles concurrent calls among multiple
// threads or processes.
pub fn create_dir_racy(path: &Path) -> io::Result<()> {

View File

@ -22,6 +22,7 @@ use rustc::middle::privacy::AccessLevels;
use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas};
use rustc::util::common::time;
use rustc::util::nodemap::{NodeSet, NodeMap};
use rustc::util::fs::rename_or_copy_remove;
use rustc_borrowck as borrowck;
use rustc_incremental::{self, IncrementalHashesMap};
use rustc_incremental::ich::Fingerprint;
@ -1084,7 +1085,7 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
// are going to build an executable
if sess.opts.output_types.contains_key(&OutputType::Exe) {
let f = outputs.path(OutputType::Object);
fs::rename(&f,
rename_or_copy_remove(&f,
f.with_file_name(format!("{}.0.o",
f.file_stem().unwrap().to_string_lossy()))).unwrap();
}