Skip to content

Commit a7bc6c3

Browse files
committed
fix windows tests
1 parent f87218a commit a7bc6c3

File tree

2 files changed

+31
-23
lines changed

2 files changed

+31
-23
lines changed

library/std/src/fs/tests.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2089,7 +2089,9 @@ fn test_rename_junction() {
20892089
#[test]
20902090
fn test_dir_smoke_test() {
20912091
let tmpdir = tmpdir();
2092-
check!(Dir::new(tmpdir.path()));
2092+
let dir = Dir::new(tmpdir.path());
2093+
println!("{dir:?}");
2094+
check!(dir);
20932095
}
20942096

20952097
#[test]

library/std/src/sys/fs/windows.rs

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,8 @@ fn run_path_with_utf16<T, P: AsRef<Path>>(
973973

974974
impl Dir {
975975
pub fn new<P: AsRef<Path>>(path: P) -> io::Result<Self> {
976-
let opts = OpenOptions::new();
976+
let mut opts = OpenOptions::new();
977+
opts.read(true);
977978
run_path_with_wcstr(path.as_ref(), &|path| Self::new_with_native(path, &opts))
978979
}
979980

@@ -987,31 +988,36 @@ impl Dir {
987988

988989
pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
989990
let mut opts = OpenOptions::new();
990-
let path = path.as_ref().as_os_str().encode_wide().collect::<Vec<_>>();
991991
opts.read(true);
992-
self.open_native(&path, &opts).map(|handle| File { handle })
992+
let path = path.as_ref();
993+
if path.is_absolute() {
994+
return File::open(path, &opts);
995+
}
996+
let path = path.as_os_str().encode_wide().collect::<Vec<_>>();
997+
self.open_native(&path, &opts, false).map(|handle| File { handle })
993998
}
994999

9951000
pub fn open_with<P: AsRef<Path>>(&self, path: P, opts: &OpenOptions) -> io::Result<File> {
9961001
let path = path.as_ref().as_os_str().encode_wide().collect::<Vec<_>>();
997-
self.open_native(&path, &opts).map(|handle| File { handle })
1002+
self.open_native(&path, &opts, false).map(|handle| File { handle })
9981003
}
9991004

10001005
pub fn open_dir<P: AsRef<Path>>(&self, path: P) -> io::Result<Self> {
10011006
let mut opts = OpenOptions::new();
10021007
let path = path.as_ref().as_os_str().encode_wide().collect::<Vec<_>>();
10031008
opts.read(true);
1004-
self.open_native(&path, &opts).map(|handle| Self { handle })
1009+
self.open_native(&path, &opts, true).map(|handle| Self { handle })
10051010
}
10061011

10071012
pub fn open_dir_with<P: AsRef<Path>>(&self, path: P, opts: &OpenOptions) -> io::Result<Self> {
10081013
let path = path.as_ref().as_os_str().encode_wide().collect::<Vec<_>>();
1009-
self.open_native(&path, &opts).map(|handle| Self { handle })
1014+
self.open_native(&path, &opts, true).map(|handle| Self { handle })
10101015
}
10111016

10121017
pub fn create_dir<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
10131018
let mut opts = OpenOptions::new();
10141019
opts.write(true);
1020+
opts.create_new(true);
10151021
run_path_with_utf16(path, &|path| self.create_dir_native(path, &opts).map(|_| ()))
10161022
}
10171023

@@ -1029,7 +1035,7 @@ impl Dir {
10291035
to_dir: &Self,
10301036
to: Q,
10311037
) -> io::Result<()> {
1032-
run_path_with_wcstr(to.as_ref(), &|to| self.rename_native(from.as_ref(), to_dir, to))
1038+
run_path_with_wcstr(to.as_ref(), &|to| self.rename_native(from.as_ref(), to_dir, to, false))
10331039
}
10341040

10351041
pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(&self, original: P, link: Q) -> io::Result<()> {
@@ -1063,16 +1069,16 @@ impl Dir {
10631069
}
10641070
}
10651071

1066-
fn open_native(&self, path: &[u16], opts: &OpenOptions) -> io::Result<Handle> {
1072+
fn open_native(&self, path: &[u16], opts: &OpenOptions, dir: bool) -> io::Result<Handle> {
10671073
let name = c::UNICODE_STRING {
1068-
Length: path.len() as _,
1069-
MaximumLength: path.len() as _,
1074+
Length: (path.len() * 2) as _,
1075+
MaximumLength: (path.len() * 2) as _,
10701076
Buffer: path.as_ptr() as *mut _,
10711077
};
10721078
let object_attributes = c::OBJECT_ATTRIBUTES {
10731079
Length: size_of::<c::OBJECT_ATTRIBUTES>() as _,
10741080
RootDirectory: self.handle.as_raw_handle(),
1075-
ObjectName: &name,
1081+
ObjectName: &raw const name,
10761082
Attributes: 0,
10771083
SecurityDescriptor: ptr::null(),
10781084
SecurityQualityOfService: ptr::null(),
@@ -1084,16 +1090,16 @@ impl Dir {
10841090
opts.get_disposition()?,
10851091
&object_attributes,
10861092
share,
1087-
false,
1093+
dir,
10881094
)
10891095
}
10901096
.io_result()
10911097
}
10921098

10931099
fn create_dir_native(&self, path: &[u16], opts: &OpenOptions) -> io::Result<Handle> {
10941100
let name = c::UNICODE_STRING {
1095-
Length: path.len() as _,
1096-
MaximumLength: path.len() as _,
1101+
Length: (path.len() * 2) as _,
1102+
MaximumLength: (path.len() * 2) as _,
10971103
Buffer: path.as_ptr() as *mut _,
10981104
};
10991105
let object_attributes = c::OBJECT_ATTRIBUTES {
@@ -1119,9 +1125,8 @@ impl Dir {
11191125

11201126
fn remove_native(&self, path: &[u16], dir: bool) -> io::Result<()> {
11211127
let mut opts = OpenOptions::new();
1122-
opts.access_mode(c::GENERIC_WRITE);
1123-
let handle =
1124-
if dir { self.create_dir_native(path, &opts) } else { self.open_native(path, &opts) }?;
1128+
opts.access_mode(c::DELETE);
1129+
let handle = self.open_native(path, &opts, dir)?;
11251130
let info = c::FILE_DISPOSITION_INFO_EX { Flags: c::FILE_DISPOSITION_FLAG_DELETE };
11261131
let result = unsafe {
11271132
c::SetFileInformationByHandle(
@@ -1134,10 +1139,11 @@ impl Dir {
11341139
if result == 0 { Err(api::get_last_error()).io_result() } else { Ok(()) }
11351140
}
11361141

1137-
fn rename_native(&self, from: &Path, to_dir: &Self, to: &WCStr) -> io::Result<()> {
1142+
fn rename_native(&self, from: &Path, to_dir: &Self, to: &WCStr, dir: bool) -> io::Result<()> {
11381143
let mut opts = OpenOptions::new();
1139-
opts.access_mode(c::GENERIC_WRITE);
1140-
let handle = run_path_with_utf16(from, &|u| self.open_native(u, &opts))?;
1144+
opts.access_mode(c::DELETE);
1145+
opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT | c::FILE_FLAG_BACKUP_SEMANTICS);
1146+
let handle = run_path_with_utf16(from, &|u| self.open_native(u, &opts, dir))?;
11411147
// Calculate the layout of the `FILE_RENAME_INFO` we pass to `SetFileInformation`
11421148
// This is a dynamically sized struct so we need to get the position of the last field to calculate the actual size.
11431149
const too_long_err: io::Error =
@@ -1149,9 +1155,9 @@ impl Dir {
11491155
.ok_or(too_long_err)?;
11501156
let layout = Layout::from_size_align(struct_size, align_of::<c::FILE_RENAME_INFO>())
11511157
.map_err(|_| too_long_err)?;
1158+
let struct_size = u32::try_from(struct_size).map_err(|_| too_long_err)?;
11521159
let to_byte_len_without_nul =
11531160
u32::try_from((to.count_bytes() - 1) * 2).map_err(|_| too_long_err)?;
1154-
let struct_size = u32::try_from(struct_size).map_err(|_| too_long_err)?;
11551161

11561162
let file_rename_info;
11571163
// SAFETY: We allocate enough memory for a full FILE_RENAME_INFO struct and a filename.
@@ -1171,7 +1177,7 @@ impl Dir {
11711177

11721178
to.as_ptr().copy_to_nonoverlapping(
11731179
(&raw mut (*file_rename_info).FileName).cast::<u16>(),
1174-
run_path_with_wcstr(from, &|s| Ok(s.count_bytes())).unwrap(),
1180+
to.count_bytes(),
11751181
);
11761182
}
11771183

0 commit comments

Comments
 (0)