Skip to content

Commit

Permalink
Rollup merge of #82177 - rylev:no-delete-bootstrap-windows, r=Mark-Si…
Browse files Browse the repository at this point in the history
…mulacrum

Do not delete bootstrap.exe on Windows during clean

Windows does not allow deleting currently running executables.

This an addition to ```@jyn514's``` change in #80574.
  • Loading branch information
JohnTitor authored Feb 21, 2021
2 parents 0fd78ed + 5b0ed02 commit 13a3c6e
Showing 1 changed file with 36 additions and 4 deletions.
40 changes: 36 additions & 4 deletions src/bootstrap/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,40 @@ fn rm_rf(path: &Path) {
}
Ok(metadata) => {
if metadata.file_type().is_file() || metadata.file_type().is_symlink() {
do_op(path, "remove file", |p| fs::remove_file(p));
do_op(path, "remove file", |p| {
fs::remove_file(p).or_else(|e| {
// Work around the fact that we cannot
// delete an executable while it runs on Windows.
#[cfg(windows)]
if e.kind() == std::io::ErrorKind::PermissionDenied
&& p.file_name().and_then(std::ffi::OsStr::to_str)
== Some("bootstrap.exe")
{
eprintln!("warning: failed to delete '{}'.", p.display());
return Ok(());
}
Err(e)
})
});
return;
}

for file in t!(fs::read_dir(path)) {
rm_rf(&t!(file).path());
}
do_op(path, "remove dir", |p| fs::remove_dir(p));
do_op(path, "remove dir", |p| {
fs::remove_dir(p).or_else(|e| {
// Check for dir not empty on Windows
#[cfg(windows)]
if matches!(e.kind(), std::io::ErrorKind::Other)
&& e.raw_os_error() == Some(145)
{
return Ok(());
}

Err(e)
})
});
}
};
}
Expand All @@ -73,12 +99,18 @@ where
// As a result, we have some special logic to remove readonly files on windows.
// This is also the reason that we can't use things like fs::remove_dir_all().
Err(ref e) if cfg!(windows) && e.kind() == ErrorKind::PermissionDenied => {
let mut p = t!(path.symlink_metadata()).permissions();
let m = t!(path.symlink_metadata());
let mut p = m.permissions();
p.set_readonly(false);
t!(fs::set_permissions(path, p));
f(path).unwrap_or_else(|e| {
// Delete symlinked directories on Windows
#[cfg(windows)]
if m.file_type().is_symlink() && path.is_dir() && fs::remove_dir(path).is_ok() {
return;
}
panic!("failed to {} {}: {}", desc, path.display(), e);
})
});
}
Err(e) => {
panic!("failed to {} {}: {}", desc, path.display(), e);
Expand Down

0 comments on commit 13a3c6e

Please sign in to comment.