Imported Upstream version 6.10.0.101

Former-commit-id: 83a210db4e58bb87425f179b210ee9c1914ac787
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-04-04 08:42:03 +00:00
parent ce8084efdb
commit 90df1c4a6a
123 changed files with 1164 additions and 454 deletions

View File

@@ -22,7 +22,7 @@ namespace System.IO.Tests
[PlatformSpecific(TestPlatforms.AnyUnix)] // Expected WatcherChangeTypes are different based on OS
public void Unix_File_Move_To_Same_Directory()
{
FileMove_SameDirectory(WatcherChangeTypes.Created | WatcherChangeTypes.Deleted);
FileMove_SameDirectory(WatcherChangeTypes.Renamed);
}
[Fact]
@@ -73,7 +73,7 @@ namespace System.IO.Tests
[PlatformSpecific(TestPlatforms.OSX)] // Expected WatcherChangeTypes are different based on OS
public void OSX_File_Move_To_Different_Watched_Directory()
{
FileMove_DifferentWatchedDirectory(WatcherChangeTypes.Changed);
FileMove_DifferentWatchedDirectory(0);
}
[Fact]
@@ -104,7 +104,7 @@ namespace System.IO.Tests
[PlatformSpecific(TestPlatforms.AnyUnix)] // Expected WatcherChangeTypes are different based on OS
public void Unix_File_Move_In_Nested_Directory(bool includeSubdirectories)
{
FileMove_NestedDirectory(includeSubdirectories ? WatcherChangeTypes.Created | WatcherChangeTypes.Deleted : 0, includeSubdirectories);
FileMove_NestedDirectory(includeSubdirectories ? WatcherChangeTypes.Renamed : 0, includeSubdirectories);
}
[Fact]
@@ -118,7 +118,7 @@ namespace System.IO.Tests
[PlatformSpecific(TestPlatforms.AnyUnix)] // Expected WatcherChangeTypes are different based on OS
public void Unix_File_Move_With_Set_NotifyFilter()
{
FileMove_WithNotifyFilter(WatcherChangeTypes.Deleted);
FileMove_WithNotifyFilter(WatcherChangeTypes.Renamed);
}
#region Test Helpers

View File

@@ -160,18 +160,19 @@ namespace System.IO
{
// The desired behavior for Move(source, dest) is to not overwrite the destination file
// if it exists. Since rename(source, dest) will replace the file at 'dest' if it exists,
// link/unlink are used instead. However, if the source path and the dest path refer to
// the same file, then do a rename rather than a link and an unlink. This is important
// for case-insensitive file systems (e.g. renaming a file in a way that just changes casing),
// so that we support changing the casing in the naming of the file. If this fails in any
// way (e.g. source file doesn't exist, dest file doesn't exist, rename fails, etc.), we
// just fall back to trying the link/unlink approach and generating any exceptional messages
// from there as necessary.
// link/unlink are used instead. Rename is more efficient than link/unlink on file systems
// where hard links are not supported (such as FAT). Therefore, given that source file exists,
// rename is used in 2 cases: when dest file does not exist or when source path and dest
// path refer to the same file (on the same device). This is important for case-insensitive
// file systems (e.g. renaming a file in a way that just changes casing), so that we support
// changing the casing in the naming of the file. If this fails in any way (e.g. source file
// doesn't exist, dest file doesn't exist, rename fails, etc.), we just fall back to trying the
// link/unlink approach and generating any exceptional messages from there as necessary.
Interop.Sys.FileStatus sourceStat, destStat;
if (Interop.Sys.LStat(sourceFullPath, out sourceStat) == 0 && // source file exists
Interop.Sys.LStat(destFullPath, out destStat) == 0 && // dest file exists
sourceStat.Dev == destStat.Dev && // source and dest are on the same device
sourceStat.Ino == destStat.Ino && // and source and dest are the same file on that device
(Interop.Sys.LStat(destFullPath, out destStat) != 0 || // dest file does not exist
(sourceStat.Dev == destStat.Dev && // source and dest are on the same device
sourceStat.Ino == destStat.Ino)) && // source and dest are the same file on that device
Interop.Sys.Rename(sourceFullPath, destFullPath) == 0) // try the rename
{
// Renamed successfully.