Skip to content

Commit 13a3c6e

Browse files
authored
Rollup merge of #82177 - rylev:no-delete-bootstrap-windows, r=Mark-Simulacrum
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.
2 parents 0fd78ed + 5b0ed02 commit 13a3c6e

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

src/bootstrap/clean.rs

+36-4
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,40 @@ fn rm_rf(path: &Path) {
5151
}
5252
Ok(metadata) => {
5353
if metadata.file_type().is_file() || metadata.file_type().is_symlink() {
54-
do_op(path, "remove file", |p| fs::remove_file(p));
54+
do_op(path, "remove file", |p| {
55+
fs::remove_file(p).or_else(|e| {
56+
// Work around the fact that we cannot
57+
// delete an executable while it runs on Windows.
58+
#[cfg(windows)]
59+
if e.kind() == std::io::ErrorKind::PermissionDenied
60+
&& p.file_name().and_then(std::ffi::OsStr::to_str)
61+
== Some("bootstrap.exe")
62+
{
63+
eprintln!("warning: failed to delete '{}'.", p.display());
64+
return Ok(());
65+
}
66+
Err(e)
67+
})
68+
});
5569
return;
5670
}
5771

5872
for file in t!(fs::read_dir(path)) {
5973
rm_rf(&t!(file).path());
6074
}
61-
do_op(path, "remove dir", |p| fs::remove_dir(p));
75+
do_op(path, "remove dir", |p| {
76+
fs::remove_dir(p).or_else(|e| {
77+
// Check for dir not empty on Windows
78+
#[cfg(windows)]
79+
if matches!(e.kind(), std::io::ErrorKind::Other)
80+
&& e.raw_os_error() == Some(145)
81+
{
82+
return Ok(());
83+
}
84+
85+
Err(e)
86+
})
87+
});
6288
}
6389
};
6490
}
@@ -73,12 +99,18 @@ where
7399
// As a result, we have some special logic to remove readonly files on windows.
74100
// This is also the reason that we can't use things like fs::remove_dir_all().
75101
Err(ref e) if cfg!(windows) && e.kind() == ErrorKind::PermissionDenied => {
76-
let mut p = t!(path.symlink_metadata()).permissions();
102+
let m = t!(path.symlink_metadata());
103+
let mut p = m.permissions();
77104
p.set_readonly(false);
78105
t!(fs::set_permissions(path, p));
79106
f(path).unwrap_or_else(|e| {
107+
// Delete symlinked directories on Windows
108+
#[cfg(windows)]
109+
if m.file_type().is_symlink() && path.is_dir() && fs::remove_dir(path).is_ok() {
110+
return;
111+
}
80112
panic!("failed to {} {}: {}", desc, path.display(), e);
81-
})
113+
});
82114
}
83115
Err(e) => {
84116
panic!("failed to {} {}: {}", desc, path.display(), e);

0 commit comments

Comments
 (0)