diff options
| author | Michael Woerister <michaelwoerister@posteo.net> | 2016-08-29 14:18:26 -0400 |
|---|---|---|
| committer | Michael Woerister <michaelwoerister@posteo.net> | 2016-08-29 14:27:40 -0400 |
| commit | bcd2f905c46158f9137fa5b63aafebcb60083385 (patch) | |
| tree | 69b547082af8462b759c378ba6980e5a9a4747e8 | |
| parent | 50b008ae3b9d15765d829ba336856f7057c9bb0c (diff) | |
| download | rust-bcd2f905c46158f9137fa5b63aafebcb60083385.tar.gz rust-bcd2f905c46158f9137fa5b63aafebcb60083385.zip | |
incr.comp.: Canonicalize path to session directory before deleteing it.
| -rw-r--r-- | src/librustc_incremental/persist/fs.rs | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs index b0d71e47e40..4ad4b115759 100644 --- a/src/librustc_incremental/persist/fs.rs +++ b/src/librustc_incremental/persist/fs.rs @@ -250,7 +250,7 @@ pub fn prepare_session_directory(tcx: TyCtxt) -> Result<bool, ()> { // Try to remove the session directory we just allocated. We don't // know if there's any garbage in it from the failed copy action. - if let Err(err) = std_fs::remove_dir_all(&session_dir) { + if let Err(err) = safe_remove_dir_all(&session_dir) { tcx.sess.warn(&format!("Failed to delete partly initialized \ session dir `{}`: {}", session_dir.display(), @@ -282,7 +282,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) { debug!("finalize_session_directory() - invalidating session directory: {}", incr_comp_session_dir.display()); - if let Err(err) = std_fs::remove_dir_all(&*incr_comp_session_dir) { + if let Err(err) = safe_remove_dir_all(&*incr_comp_session_dir) { sess.warn(&format!("Error deleting incremental compilation \ session directory `{}`: {}", incr_comp_session_dir.display(), @@ -460,7 +460,7 @@ fn lock_directory(sess: &Session, fn delete_session_dir_lock_file(sess: &Session, lock_file_path: &Path) { - if let Err(err) = std_fs::remove_file(&lock_file_path) { + if let Err(err) = safe_remove_file(&lock_file_path) { sess.warn(&format!("Error deleting lock file for incremental \ compilation session directory `{}`: {}", lock_file_path.display(), @@ -841,7 +841,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { debug!("garbage_collect_session_directories() - deleting `{}`", path.display()); - if let Err(err) = std_fs::remove_dir_all(&path) { + if let Err(err) = safe_remove_dir_all(&path) { sess.warn(&format!("Failed to garbage collect finalized incremental \ compilation session directory `{}`: {}", path.display(), @@ -860,7 +860,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { debug!("garbage_collect_session_directories() - deleting `{}`", path.display()); - if let Err(err) = std_fs::remove_dir_all(&path) { + if let Err(err) = safe_remove_dir_all(&path) { sess.warn(&format!("Failed to garbage collect incremental \ compilation session directory `{}`: {}", path.display(), @@ -893,6 +893,30 @@ fn all_except_most_recent(deletion_candidates: Vec<(SystemTime, PathBuf, Option< } } +/// Since paths of artifacts within session directories can get quite long, we +/// need to support deleting files with very long paths. The regular +/// WinApi functions only support paths up to 260 characters, however. In order +/// to circumvent this limitation, we canonicalize the path of the directory +/// before passing it to std::fs::remove_dir_all(). This will convert the path +/// into the '\\?\' format, which supports much longer paths. +fn safe_remove_dir_all(p: &Path) -> io::Result<()> { + if p.exists() { + let canonicalized = try!(p.canonicalize()); + std_fs::remove_dir_all(canonicalized) + } else { + Ok(()) + } +} + +fn safe_remove_file(p: &Path) -> io::Result<()> { + if p.exists() { + let canonicalized = try!(p.canonicalize()); + std_fs::remove_file(canonicalized) + } else { + Ok(()) + } +} + #[test] fn test_all_except_most_recent() { assert_eq!(all_except_most_recent( |
