You've already forked linux-packaging-mono
Imported Upstream version 6.4.0.150
Former-commit-id: 2cf3acd45014a53dda66c13f7378a88695d3c93e
This commit is contained in:
parent
7eed0321b0
commit
345224e2bc
@@ -12,6 +12,32 @@ namespace System.IO
|
||||
{
|
||||
internal const int DefaultBufferSize = 4096;
|
||||
|
||||
private static bool CopyDanglingSymlink(string sourceFullPath, string destFullPath)
|
||||
{
|
||||
// Check if the source is a dangling symlink. In those cases, we just want to copy the link
|
||||
Interop.Sys.FileStatus ignored;
|
||||
if (! (Interop.Sys.Stat(sourceFullPath, out ignored) < 0 &&
|
||||
Interop.Sys.LStat(sourceFullPath, out ignored) == 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Interop.ErrorInfo errorInfo;
|
||||
// get the target of the symlink
|
||||
string linkTarget = Interop.Sys.ReadLink(sourceFullPath);
|
||||
if (linkTarget == null)
|
||||
{
|
||||
errorInfo = Interop.Sys.GetLastErrorInfo();
|
||||
throw Interop.GetExceptionForIoErrno(errorInfo, sourceFullPath);
|
||||
}
|
||||
|
||||
if (Interop.Sys.Symlink(linkTarget, destFullPath) == 0)
|
||||
return true;
|
||||
|
||||
errorInfo = Interop.Sys.GetLastErrorInfo();
|
||||
throw Interop.GetExceptionForIoErrno(errorInfo, destFullPath);
|
||||
}
|
||||
|
||||
public static void CopyFile(string sourceFullPath, string destFullPath, bool overwrite)
|
||||
{
|
||||
// The destination path may just be a directory into which the file should be copied.
|
||||
@@ -21,6 +47,9 @@ namespace System.IO
|
||||
destFullPath = Path.Combine(destFullPath, Path.GetFileName(sourceFullPath));
|
||||
}
|
||||
|
||||
if (CopyDanglingSymlink(sourceFullPath, destFullPath))
|
||||
return;
|
||||
|
||||
// Copy the contents of the file from the source to the destination, creating the destination in the process
|
||||
using (var src = new FileStream(sourceFullPath, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultBufferSize, FileOptions.None))
|
||||
using (var dst = new FileStream(destFullPath, overwrite ? FileMode.Create : FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None, DefaultBufferSize, FileOptions.None))
|
||||
@@ -31,6 +60,9 @@ namespace System.IO
|
||||
|
||||
private static void LinkOrCopyFile (string sourceFullPath, string destFullPath)
|
||||
{
|
||||
if (CopyDanglingSymlink(sourceFullPath, destFullPath))
|
||||
return;
|
||||
|
||||
if (Interop.Sys.Link(sourceFullPath, destFullPath) >= 0)
|
||||
return;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System.IO.Tests
|
||||
{
|
||||
@@ -48,6 +49,22 @@ namespace System.IO.Tests
|
||||
Assert.Throws<IOException>(() => Copy(testFile, testFile));
|
||||
}
|
||||
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
private static extern int symlink(string target, string linkpath);
|
||||
|
||||
[Fact]
|
||||
[PlatformSpecific(TestPlatforms.AnyUnix)]
|
||||
public void DanglingSymlinkCopy()
|
||||
{
|
||||
string dangling_symlink = GetTestFileName();
|
||||
string missing_target = GetTestFileName();
|
||||
string dangling_symlink_new_location = GetTestFileName();
|
||||
Assert.False(File.Exists(missing_target));
|
||||
Assert.Equal(symlink(missing_target, dangling_symlink), 0);
|
||||
Copy(dangling_symlink, dangling_symlink_new_location);
|
||||
Assert.True(File.Exists(dangling_symlink_new_location)); // File.Exists returns true for dangling symlinks
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[SkipOnTargetFramework(TargetFrameworkMonikers.Mono, "CoreFX FileStream not yet imported")]
|
||||
public void NonExistentPath()
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using Xunit;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System.IO.Tests
|
||||
{
|
||||
@@ -174,6 +175,22 @@ namespace System.IO.Tests
|
||||
Assert.False(File.Exists(testFileSource.FullName));
|
||||
}
|
||||
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
private static extern int symlink(string target, string linkpath);
|
||||
|
||||
[Fact]
|
||||
[PlatformSpecific(TestPlatforms.AnyUnix)]
|
||||
public void DanglingSymlinkMove()
|
||||
{
|
||||
string dangling_symlink = GetTestFileName();
|
||||
string missing_target = GetTestFileName();
|
||||
string dangling_symlink_new_location = GetTestFileName();
|
||||
Assert.False(File.Exists(missing_target));
|
||||
Assert.Equal(symlink(missing_target, dangling_symlink), 0);
|
||||
Move(dangling_symlink, dangling_symlink_new_location);
|
||||
Assert.True(File.Exists(dangling_symlink_new_location)); // File.Exists returns true for dangling symlinks
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FileNameWithSignificantWhitespace()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user