Skip to content

Commit

Permalink
Windows: remove readonly files
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisDenton authored and gitbot committed Feb 20, 2025
1 parent d49e4a6 commit 89f2005
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
2 changes: 1 addition & 1 deletion std/src/fs/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1384,7 +1384,7 @@ fn file_try_clone() {
}

#[test]
#[cfg(not(windows))]
#[cfg(not(target_vendor = "win7"))]
fn unlink_readonly() {
let tmpdir = tmpdir();
let path = tmpdir.join("file");
Expand Down
24 changes: 22 additions & 2 deletions std/src/sys/pal/windows/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ impl OpenOptions {
impl File {
pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
let path = maybe_verbatim(path)?;
Self::open_native(&path, opts)
}

fn open_native(path: &[u16], opts: &OpenOptions) -> io::Result<File> {
let creation = opts.get_creation_mode()?;
let handle = unsafe {
c::CreateFileW(
Expand Down Expand Up @@ -1226,8 +1230,24 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {

pub fn unlink(p: &Path) -> io::Result<()> {
let p_u16s = maybe_verbatim(p)?;
cvt(unsafe { c::DeleteFileW(p_u16s.as_ptr()) })?;
Ok(())
if unsafe { c::DeleteFileW(p_u16s.as_ptr()) } == 0 {
let err = api::get_last_error();
// if `DeleteFileW` fails with ERROR_ACCESS_DENIED then try to remove
// the file while ignoring the readonly attribute.
// This is accomplished by calling the `posix_delete` function on an open file handle.
if err == WinError::ACCESS_DENIED {
let mut opts = OpenOptions::new();
opts.access_mode(c::DELETE);
opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT);
if File::open_native(&p_u16s, &opts).map(|f| f.posix_delete()).is_ok() {
return Ok(());
}
}
// return the original error if any of the above fails.
Err(io::Error::from_raw_os_error(err.code as i32))
} else {
Ok(())
}
}

pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
Expand Down

0 comments on commit 89f2005

Please sign in to comment.