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:
@@ -1132,9 +1132,14 @@ fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io
|
|||||||
&dir,
|
&dir,
|
||||||
&name,
|
&name,
|
||||||
c::SYNCHRONIZE | c::DELETE | c::FILE_LIST_DIRECTORY,
|
c::SYNCHRONIZE | c::DELETE | c::FILE_LIST_DIRECTORY,
|
||||||
)?;
|
);
|
||||||
|
// 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);
|
dirlist.push(child_dir);
|
||||||
} else {
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
for i in 1..=MAX_RETRIES {
|
for i in 1..=MAX_RETRIES {
|
||||||
let result = open_link_no_reparse(&dir, &name, c::SYNCHRONIZE | c::DELETE);
|
let result = open_link_no_reparse(&dir, &name, c::SYNCHRONIZE | c::DELETE);
|
||||||
match result {
|
match result {
|
||||||
@@ -1145,15 +1150,13 @@ fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io
|
|||||||
Err(e)
|
Err(e)
|
||||||
if i < MAX_RETRIES
|
if i < MAX_RETRIES
|
||||||
&& (e.raw_os_error() == Some(c::ERROR_DELETE_PENDING as _)
|
&& (e.raw_os_error() == Some(c::ERROR_DELETE_PENDING as _)
|
||||||
|| e.raw_os_error()
|
|| e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as _)) => {}
|
||||||
== Some(c::ERROR_SHARING_VIOLATION as _)) => {}
|
|
||||||
// Otherwise return the error.
|
// Otherwise return the error.
|
||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
thread::yield_now();
|
thread::yield_now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// If there were no more files then delete the directory.
|
// If there were no more files then delete the directory.
|
||||||
if !more_data {
|
if !more_data {
|
||||||
if let Some(dir) = dirlist.pop() {
|
if let Some(dir) = dirlist.pop() {
|
||||||
|
|||||||
Reference in New Issue
Block a user