35 lines
1.0 KiB
C#
35 lines
1.0 KiB
C#
using System.Runtime.InteropServices;
|
|||
|
|
|
||
|
|
namespace PrivaPub.Infrastructure.Backup
|
||
|
|
{
|
||
|
|
// A second name for a file (.NET has no API for it): a backup links the live media, which costs no disk, since names are
|
||
|
|
// random and files never change; deleting the live one leaves the backup's.
|
||
|
|
static class HardLink
|
||
|
|
{
|
||
|
|
// strings go to libc as UTF-8 on Unix
|
||
|
|
[DllImport("libc", EntryPoint = "link", SetLastError = true, CharSet = CharSet.Ansi)]
|
||
|
|
static extern int Link(string existing, string created);
|
||
|
|
|
||
|
|
/// <summary>Links, or copies where a link can't be made (another disk, a filesystem refusing it).</summary>
|
||
|
|
public static bool LinkOrCopy(string existing, string created)
|
||
|
|
{
|
||
|
|
Directory.CreateDirectory(Path.GetDirectoryName(created)!);
|
||
|
|
if (OperatingSystem.IsLinux())
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
if (Link(existing, created) == 0)
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
catch (DllNotFoundException)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
catch (EntryPointNotFoundException)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
}
|
||
|
|
File.Copy(existing, created, overwrite: true);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|