Use libc directly instead of Mono.Posix
parent
711888ebe9
commit
0a1e3bf6b0
@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace DepotDownloader
|
||||
{
|
||||
public static class UnixUtilities
|
||||
{
|
||||
[Flags]
|
||||
private enum FilePermissions : uint
|
||||
{
|
||||
S_ISUID = 0x0800, // Set user ID on execution
|
||||
S_ISGID = 0x0400, // Set group ID on execution
|
||||
S_ISVTX = 0x0200, // Save swapped text after use (sticky).
|
||||
S_IRUSR = 0x0100, // Read by owner
|
||||
S_IWUSR = 0x0080, // Write by owner
|
||||
S_IXUSR = 0x0040, // Execute by owner
|
||||
S_IRGRP = 0x0020, // Read by group
|
||||
S_IWGRP = 0x0010, // Write by group
|
||||
S_IXGRP = 0x0008, // Execute by group
|
||||
S_IROTH = 0x0004, // Read by other
|
||||
S_IWOTH = 0x0002, // Write by other
|
||||
S_IXOTH = 0x0001, // Execute by other
|
||||
|
||||
S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR,
|
||||
S_IRWXG = S_IRGRP | S_IWGRP | S_IXGRP,
|
||||
S_IRWXO = S_IROTH | S_IWOTH | S_IXOTH,
|
||||
ACCESSPERMS = S_IRWXU | S_IRWXG | S_IRWXO, // 0777
|
||||
ALLPERMS = S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, // 07777
|
||||
DEFFILEMODE = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, // 0666
|
||||
EXECUTE = S_IXGRP | S_IXUSR | S_IXOTH,
|
||||
|
||||
// Device types
|
||||
S_IFMT = 0xF000, // Bits which determine file type
|
||||
S_IFDIR = 0x4000, // Directory
|
||||
S_IFCHR = 0x2000, // Character device
|
||||
S_IFBLK = 0x6000, // Block device
|
||||
S_IFREG = 0x8000, // Regular file
|
||||
S_IFIFO = 0x1000, // FIFO
|
||||
S_IFLNK = 0xA000, // Symbolic link
|
||||
S_IFSOCK = 0xC000, // Socket
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 144)]
|
||||
private readonly struct Stat
|
||||
{
|
||||
[FieldOffset(sizeof(ulong) * 3)]
|
||||
public readonly FilePermissions st_mode;
|
||||
}
|
||||
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
private static extern int stat(string path, out Stat stat);
|
||||
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
private static extern int chmod(string path, FilePermissions mode);
|
||||
|
||||
[DllImport("libc", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
|
||||
private static extern IntPtr strerror(int errno);
|
||||
|
||||
private static void ThrowIf(int i)
|
||||
{
|
||||
if (i == -1)
|
||||
{
|
||||
var errno = Marshal.GetLastWin32Error();
|
||||
throw new Exception(Marshal.PtrToStringAnsi(strerror(errno)));
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetExecute(string path, bool value)
|
||||
{
|
||||
ThrowIf(UnixUtilities.stat(path, out var stat));
|
||||
|
||||
if (stat.st_mode.HasFlag(FilePermissions.EXECUTE) != value)
|
||||
{
|
||||
ThrowIf(chmod(path, value
|
||||
? stat.st_mode | FilePermissions.EXECUTE
|
||||
: stat.st_mode & ~FilePermissions.EXECUTE));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue