Skip to content

Commit bcd2f90

Browse files
incr.comp.: Canonicalize path to session directory before deleteing it.
1 parent 50b008a commit bcd2f90

File tree

1 file changed

+29
-5
lines changed
  • src/librustc_incremental/persist

1 file changed

+29
-5
lines changed

src/librustc_incremental/persist/fs.rs

+29-5
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ pub fn prepare_session_directory(tcx: TyCtxt) -> Result<bool, ()> {
250250

251251
// Try to remove the session directory we just allocated. We don't
252252
// know if there's any garbage in it from the failed copy action.
253-
if let Err(err) = std_fs::remove_dir_all(&session_dir) {
253+
if let Err(err) = safe_remove_dir_all(&session_dir) {
254254
tcx.sess.warn(&format!("Failed to delete partly initialized \
255255
session dir `{}`: {}",
256256
session_dir.display(),
@@ -282,7 +282,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
282282
debug!("finalize_session_directory() - invalidating session directory: {}",
283283
incr_comp_session_dir.display());
284284

285-
if let Err(err) = std_fs::remove_dir_all(&*incr_comp_session_dir) {
285+
if let Err(err) = safe_remove_dir_all(&*incr_comp_session_dir) {
286286
sess.warn(&format!("Error deleting incremental compilation \
287287
session directory `{}`: {}",
288288
incr_comp_session_dir.display(),
@@ -460,7 +460,7 @@ fn lock_directory(sess: &Session,
460460

461461
fn delete_session_dir_lock_file(sess: &Session,
462462
lock_file_path: &Path) {
463-
if let Err(err) = std_fs::remove_file(&lock_file_path) {
463+
if let Err(err) = safe_remove_file(&lock_file_path) {
464464
sess.warn(&format!("Error deleting lock file for incremental \
465465
compilation session directory `{}`: {}",
466466
lock_file_path.display(),
@@ -841,7 +841,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> {
841841
debug!("garbage_collect_session_directories() - deleting `{}`",
842842
path.display());
843843

844-
if let Err(err) = std_fs::remove_dir_all(&path) {
844+
if let Err(err) = safe_remove_dir_all(&path) {
845845
sess.warn(&format!("Failed to garbage collect finalized incremental \
846846
compilation session directory `{}`: {}",
847847
path.display(),
@@ -860,7 +860,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> {
860860
debug!("garbage_collect_session_directories() - deleting `{}`",
861861
path.display());
862862

863-
if let Err(err) = std_fs::remove_dir_all(&path) {
863+
if let Err(err) = safe_remove_dir_all(&path) {
864864
sess.warn(&format!("Failed to garbage collect incremental \
865865
compilation session directory `{}`: {}",
866866
path.display(),
@@ -893,6 +893,30 @@ fn all_except_most_recent(deletion_candidates: Vec<(SystemTime, PathBuf, Option<
893893
}
894894
}
895895

896+
/// Since paths of artifacts within session directories can get quite long, we
897+
/// need to support deleting files with very long paths. The regular
898+
/// WinApi functions only support paths up to 260 characters, however. In order
899+
/// to circumvent this limitation, we canonicalize the path of the directory
900+
/// before passing it to std::fs::remove_dir_all(). This will convert the path
901+
/// into the '\\?\' format, which supports much longer paths.
902+
fn safe_remove_dir_all(p: &Path) -> io::Result<()> {
903+
if p.exists() {
904+
let canonicalized = try!(p.canonicalize());
905+
std_fs::remove_dir_all(canonicalized)
906+
} else {
907+
Ok(())
908+
}
909+
}
910+
911+
fn safe_remove_file(p: &Path) -> io::Result<()> {
912+
if p.exists() {
913+
let canonicalized = try!(p.canonicalize());
914+
std_fs::remove_file(canonicalized)
915+
} else {
916+
Ok(())
917+
}
918+
}
919+
896920
#[test]
897921
fn test_all_except_most_recent() {
898922
assert_eq!(all_except_most_recent(

0 commit comments

Comments
 (0)