This repository was archived by the owner on May 28, 2025. It is now read-only.
File tree Expand file tree Collapse file tree 2 files changed +39
-7
lines changed Expand file tree Collapse file tree 2 files changed +39
-7
lines changed Original file line number Diff line number Diff line change @@ -1953,3 +1953,32 @@ fn test_rename_directory_to_non_empty_directory() {
1953
1953
1954
1954
error!(fs::rename(source_path, target_path), 145); // ERROR_DIR_NOT_EMPTY
1955
1955
}
1956
+
1957
+ #[test]
1958
+ fn test_rename_symlink() {
1959
+ let tmpdir = tmpdir();
1960
+ let original = tmpdir.join("original");
1961
+ let dest = tmpdir.join("dest");
1962
+ let not_exist = Path::new("does not exist");
1963
+
1964
+ symlink_file(not_exist, &original).unwrap();
1965
+ fs::rename(&original, &dest).unwrap();
1966
+ // Make sure that renaming `original` to `dest` preserves the symlink.
1967
+ assert_eq!(fs::read_link(&dest).unwrap().as_path(), not_exist);
1968
+ }
1969
+
1970
+ #[test]
1971
+ #[cfg(windows)]
1972
+ fn test_rename_junction() {
1973
+ let tmpdir = tmpdir();
1974
+ let original = tmpdir.join("original");
1975
+ let dest = tmpdir.join("dest");
1976
+ let not_exist = Path::new("does not exist");
1977
+
1978
+ junction_point(¬_exist, &original).unwrap();
1979
+ fs::rename(&original, &dest).unwrap();
1980
+
1981
+ // Make sure that renaming `original` to `dest` preserves the junction point.
1982
+ // Junction links are always absolute so we just check the file name is correct.
1983
+ assert_eq!(fs::read_link(&dest).unwrap().file_name(), Some(not_exist.as_os_str()));
1984
+ }
Original file line number Diff line number Diff line change @@ -1295,15 +1295,18 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
1295
1295
} else {
1296
1296
// SAFETY: The struct has been initialized by GetFileInformationByHandleEx
1297
1297
let file_attribute_tag_info = unsafe { file_attribute_tag_info.assume_init() };
1298
+ let file_type = FileType::new(
1299
+ file_attribute_tag_info.FileAttributes,
1300
+ file_attribute_tag_info.ReparseTag,
1301
+ );
1298
1302
1299
- if file_attribute_tag_info.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0
1300
- && file_attribute_tag_info.ReparseTag != c::IO_REPARSE_TAG_MOUNT_POINT
1301
- {
1302
- // The file is not a mount point: Reopen the file without inhibiting reparse point behavior.
1303
- None
1304
- } else {
1305
- // The file is a mount point: Don't reopen the file so that the mount point gets renamed.
1303
+ if file_type.is_symlink() {
1304
+ // The file is a mount point, junction point or symlink so
1305
+ // don't reopen the file so that the link gets renamed.
1306
1306
Some(Ok(handle))
1307
+ } else {
1308
+ // Otherwise reopen the file without inhibiting reparse point behavior.
1309
+ None
1307
1310
}
1308
1311
}
1309
1312
}
You can’t perform that action at this time.
0 commit comments