mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
remove_dir_all: delete directory with fewer perms
If opening a directory with `FILE_LIST_DIRECTORY` access fails then we should try opening without requesting that access. We may still be able to delete it if it's empty or a link.
This commit is contained in:
parent
1a6ae3d692
commit
ddff7f0e50
@ -1132,27 +1132,30 @@ fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io
|
||||
&dir,
|
||||
&name,
|
||||
c::SYNCHRONIZE | c::DELETE | c::FILE_LIST_DIRECTORY,
|
||||
)?;
|
||||
dirlist.push(child_dir);
|
||||
} else {
|
||||
for i in 1..=MAX_RETRIES {
|
||||
let result = open_link_no_reparse(&dir, &name, c::SYNCHRONIZE | c::DELETE);
|
||||
match result {
|
||||
Ok(f) => delete(&f)?,
|
||||
// Already deleted, so skip.
|
||||
Err(e) if e.kind() == io::ErrorKind::NotFound => break,
|
||||
// Retry a few times if the file is locked or a delete is already in progress.
|
||||
Err(e)
|
||||
if i < MAX_RETRIES
|
||||
&& (e.raw_os_error() == Some(c::ERROR_DELETE_PENDING as _)
|
||||
|| e.raw_os_error()
|
||||
== Some(c::ERROR_SHARING_VIOLATION as _)) => {}
|
||||
// Otherwise return the error.
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
thread::yield_now();
|
||||
);
|
||||
// On success, add the handle to the queue.
|
||||
// If opening the directory fails we treat it the same as a file
|
||||
if let Ok(child_dir) = child_dir {
|
||||
dirlist.push(child_dir);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for i in 1..=MAX_RETRIES {
|
||||
let result = open_link_no_reparse(&dir, &name, c::SYNCHRONIZE | c::DELETE);
|
||||
match result {
|
||||
Ok(f) => delete(&f)?,
|
||||
// Already deleted, so skip.
|
||||
Err(e) if e.kind() == io::ErrorKind::NotFound => break,
|
||||
// Retry a few times if the file is locked or a delete is already in progress.
|
||||
Err(e)
|
||||
if i < MAX_RETRIES
|
||||
&& (e.raw_os_error() == Some(c::ERROR_DELETE_PENDING as _)
|
||||
|| e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as _)) => {}
|
||||
// Otherwise return the error.
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
thread::yield_now();
|
||||
}
|
||||
}
|
||||
// If there were no more files then delete the directory.
|
||||
if !more_data {
|
||||
|
Loading…
Reference in New Issue
Block a user