Skip to content

Commit be60aa1

Browse files
committed
fix windows tests
1 parent 7b25da5 commit be60aa1

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
@@ -968,7 +968,8 @@ fn run_path_with_utf16<T, P: AsRef<Path>>(
968968

969969
impl Dir {
970970
pub fn new<P: AsRef<Path>>(path: P) -> io::Result<Self> {
971-
let opts = OpenOptions::new();
971+
let mut opts = OpenOptions::new();
972+
opts.read(true);
972973
run_path_with_wcstr(path.as_ref(), &|path| Self::new_with_native(path, &opts))
973974
}
974975

@@ -982,31 +983,36 @@ impl Dir {
982983

983984
pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
984985
let mut opts = OpenOptions::new();
985-
let path = path.as_ref().as_os_str().encode_wide().collect::<Vec<_>>();
986986
opts.read(true);
987-
self.open_native(&path, &opts).map(|handle| File { handle })
987+
let path = path.as_ref();
988+
if path.is_absolute() {
989+
return File::open(path, &opts);
990+
}
991+
let path = path.as_os_str().encode_wide().collect::<Vec<_>>();
992+
self.open_native(&path, &opts, false).map(|handle| File { handle })
988993
}
989994

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

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

10021007
pub fn open_dir_with<P: AsRef<Path>>(&self, path: P, opts: &OpenOptions) -> io::Result<Self> {
10031008
let path = path.as_ref().as_os_str().encode_wide().collect::<Vec<_>>();
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 create_dir<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
10081013
let mut opts = OpenOptions::new();
10091014
opts.write(true);
1015+
opts.create_new(true);
10101016
run_path_with_utf16(path, &|path| self.create_dir_native(path, &opts).map(|_| ()))
10111017
}
10121018

@@ -1024,7 +1030,7 @@ impl Dir {
10241030
to_dir: &Self,
10251031
to: Q,
10261032
) -> io::Result<()> {
1027-
run_path_with_wcstr(to.as_ref(), &|to| self.rename_native(from.as_ref(), to_dir, to))
1033+
run_path_with_wcstr(to.as_ref(), &|to| self.rename_native(from.as_ref(), to_dir, to, false))
10281034
}
10291035

10301036
pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(&self, original: P, link: Q) -> io::Result<()> {
@@ -1058,16 +1064,16 @@ impl Dir {
10581064
}
10591065
}
10601066

1061-
fn open_native(&self, path: &[u16], opts: &OpenOptions) -> io::Result<Handle> {
1067+
fn open_native(&self, path: &[u16], opts: &OpenOptions, dir: bool) -> io::Result<Handle> {
10621068
let name = c::UNICODE_STRING {
1063-
Length: path.len() as _,
1064-
MaximumLength: path.len() as _,
1069+
Length: (path.len() * 2) as _,
1070+
MaximumLength: (path.len() * 2) as _,
10651071
Buffer: path.as_ptr() as *mut _,
10661072
};
10671073
let object_attributes = c::OBJECT_ATTRIBUTES {
10681074
Length: size_of::<c::OBJECT_ATTRIBUTES>() as _,
10691075
RootDirectory: self.handle.as_raw_handle(),
1070-
ObjectName: &name,
1076+
ObjectName: &raw const name,
10711077
Attributes: 0,
10721078
SecurityDescriptor: ptr::null(),
10731079
SecurityQualityOfService: ptr::null(),
@@ -1079,16 +1085,16 @@ impl Dir {
10791085
opts.get_disposition()?,
10801086
&object_attributes,
10811087
share,
1082-
false,
1088+
dir,
10831089
)
10841090
}
10851091
.io_result()
10861092
}
10871093

10881094
fn create_dir_native(&self, path: &[u16], opts: &OpenOptions) -> io::Result<Handle> {
10891095
let name = c::UNICODE_STRING {
1090-
Length: path.len() as _,
1091-
MaximumLength: path.len() as _,
1096+
Length: (path.len() * 2) as _,
1097+
MaximumLength: (path.len() * 2) as _,
10921098
Buffer: path.as_ptr() as *mut _,
10931099
};
10941100
let object_attributes = c::OBJECT_ATTRIBUTES {
@@ -1114,9 +1120,8 @@ impl Dir {
11141120

11151121
fn remove_native(&self, path: &[u16], dir: bool) -> io::Result<()> {
11161122
let mut opts = OpenOptions::new();
1117-
opts.access_mode(c::GENERIC_WRITE);
1118-
let handle =
1119-
if dir { self.create_dir_native(path, &opts) } else { self.open_native(path, &opts) }?;
1123+
opts.access_mode(c::DELETE);
1124+
let handle = self.open_native(path, &opts, dir)?;
11201125
let info = c::FILE_DISPOSITION_INFO_EX { Flags: c::FILE_DISPOSITION_FLAG_DELETE };
11211126
let result = unsafe {
11221127
c::SetFileInformationByHandle(
@@ -1129,10 +1134,11 @@ impl Dir {
11291134
if result == 0 { Err(api::get_last_error()).io_result() } else { Ok(()) }
11301135
}
11311136

1132-
fn rename_native(&self, from: &Path, to_dir: &Self, to: &WCStr) -> io::Result<()> {
1137+
fn rename_native(&self, from: &Path, to_dir: &Self, to: &WCStr, dir: bool) -> io::Result<()> {
11331138
let mut opts = OpenOptions::new();
1134-
opts.access_mode(c::GENERIC_WRITE);
1135-
let handle = run_path_with_utf16(from, &|u| self.open_native(u, &opts))?;
1139+
opts.access_mode(c::DELETE);
1140+
opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT | c::FILE_FLAG_BACKUP_SEMANTICS);
1141+
let handle = run_path_with_utf16(from, &|u| self.open_native(u, &opts, dir))?;
11361142
// Calculate the layout of the `FILE_RENAME_INFO` we pass to `SetFileInformation`
11371143
// This is a dynamically sized struct so we need to get the position of the last field to calculate the actual size.
11381144
const too_long_err: io::Error =
@@ -1144,9 +1150,9 @@ impl Dir {
11441150
.ok_or(too_long_err)?;
11451151
let layout = Layout::from_size_align(struct_size, align_of::<c::FILE_RENAME_INFO>())
11461152
.map_err(|_| too_long_err)?;
1153+
let struct_size = u32::try_from(struct_size).map_err(|_| too_long_err)?;
11471154
let to_byte_len_without_nul =
11481155
u32::try_from((to.count_bytes() - 1) * 2).map_err(|_| too_long_err)?;
1149-
let struct_size = u32::try_from(struct_size).map_err(|_| too_long_err)?;
11501156

11511157
let file_rename_info;
11521158
// SAFETY: We allocate enough memory for a full FILE_RENAME_INFO struct and a filename.
@@ -1166,7 +1172,7 @@ impl Dir {
11661172

11671173
to.as_ptr().copy_to_nonoverlapping(
11681174
(&raw mut (*file_rename_info).FileName).cast::<u16>(),
1169-
run_path_with_wcstr(from, &|s| Ok(s.count_bytes())).unwrap(),
1175+
to.count_bytes(),
11701176
);
11711177
}
11721178

0 commit comments

Comments
 (0)