Skip to content

Commit

Permalink
Unrolled build for rust-lang#129934
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#129934 - ChrisDenton:remove-dir-all3, r=Amanieu

Win: Open dir for sync access in remove_dir_all

A small follow up to rust-lang#129800.

We should explicitly open directories for synchronous access. We ultimately use `GetFileInformationByHandleEx` to read directories which should paper over any issues caused by using async directory reads (or else return an error) but it's better to do the right thing in the first place. Note though that `delete` does not read or write any data so it's not necessary there.
  • Loading branch information
rust-timer authored Sep 19, 2024
2 parents f79a912 + 6b0fc97 commit 37d3b06
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions library/std/src/sys/pal/windows/fs/remove_dir_all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,12 @@ unsafe fn nt_open_file(
}

/// Open the file `path` in the directory `parent`, requesting the given `access` rights.
/// `options` will be OR'd with `FILE_OPEN_REPARSE_POINT`.
fn open_link_no_reparse(
parent: &File,
path: &[u16],
access: u32,
options: u32,
) -> Result<Option<File>, WinError> {
// This is implemented using the lower level `NtOpenFile` function as
// unfortunately opening a file relative to a parent is not supported by
Expand All @@ -96,7 +98,7 @@ fn open_link_no_reparse(
..c::OBJECT_ATTRIBUTES::default()
};
let share = c::FILE_SHARE_DELETE | c::FILE_SHARE_READ | c::FILE_SHARE_WRITE;
let options = c::FILE_OPEN_REPARSE_POINT;
let options = c::FILE_OPEN_REPARSE_POINT | options;
let result = nt_open_file(access, &object, share, options);

// Retry without OBJ_DONT_REPARSE if it's not supported.
Expand Down Expand Up @@ -128,13 +130,20 @@ fn open_link_no_reparse(
}

fn open_dir(parent: &File, name: &[u16]) -> Result<Option<File>, WinError> {
open_link_no_reparse(parent, name, c::SYNCHRONIZE | c::FILE_LIST_DIRECTORY)
// Open the directory for synchronous directory listing.
open_link_no_reparse(
parent,
name,
c::SYNCHRONIZE | c::FILE_LIST_DIRECTORY,
// "_IO_NONALERT" means that a synchronous call won't be interrupted.
c::FILE_SYNCHRONOUS_IO_NONALERT,
)
}

fn delete(parent: &File, name: &[u16]) -> Result<(), WinError> {
// Note that the `delete` function consumes the opened file to ensure it's
// dropped immediately. See module comments for why this is important.
match open_link_no_reparse(parent, name, c::SYNCHRONIZE | c::DELETE) {
match open_link_no_reparse(parent, name, c::DELETE, 0) {
Ok(Some(f)) => f.delete(),
Ok(None) => Ok(()),
Err(e) => Err(e),
Expand Down

0 comments on commit 37d3b06

Please sign in to comment.