|
2 | 2 | //
|
3 | 3 | // SPDX-License-Identifier: MIT
|
4 | 4 |
|
5 |
| -using System; |
6 | 5 | using System.IO;
|
7 | 6 | using System.Runtime.InteropServices;
|
8 | 7 |
|
9 | 8 | namespace Cesium.Sdk;
|
10 | 9 |
|
11 |
| -[Flags] |
12 |
| -public enum FilePermissions |
| 10 | +internal static class FileSystemUtil |
13 | 11 | {
|
14 |
| - None = 0, |
15 |
| - OtherExecute = 1, |
16 |
| - OtherWrite = 2, |
17 |
| - OtherRead = 4, |
18 |
| - GroupExecute = 8, |
19 |
| - GroupWrite = 16, |
20 |
| - GroupRead = 32, |
21 |
| - UserExecute = 64, |
22 |
| - UserWrite = 128, |
23 |
| - UserRead = 256, |
24 |
| - StickyBit = 512, |
25 |
| - SetGroup = 1024, |
26 |
| - SetUser = 2048, |
27 |
| -} |
28 |
| - |
29 |
| -internal class UnixFileInfo |
30 |
| -{ |
31 |
| - private FileStatus _status; |
32 |
| - |
33 |
| - public UnixFileInfo(string path) |
34 |
| - { |
35 |
| - LoadFileStatus(path); |
36 |
| - } |
37 |
| - |
38 |
| - private void LoadFileStatus(string path) |
39 |
| - { |
40 |
| - int rv = FileInterop.LStat(path, out _status); |
41 |
| - |
42 |
| - Console.WriteLine($"LStat: {rv}"); |
43 |
| - if (rv < 0) |
44 |
| - { |
45 |
| - var error = Marshal.GetLastWin32Error(); |
46 |
| - |
47 |
| - throw (Error)error switch |
48 |
| - { |
49 |
| - Error.ENOENT => |
50 |
| - new ArgumentException("No such file or directory", nameof(path)), |
51 |
| - Error.ENOTDIR => |
52 |
| - new ArgumentException("A component of the path is not a directory", nameof(path)), |
53 |
| - _ => |
54 |
| - new InvalidOperationException($"lstat failed for {path} with error {error}") |
55 |
| - }; |
56 |
| - } |
57 |
| - |
58 |
| - uint fileType = _status.st_mode & FileTypes.S_IFMT; |
59 |
| - if (fileType != FileTypes.S_IFLNK) |
60 |
| - return; |
| 12 | + [DllImport("libc", EntryPoint = "access", SetLastError = true)] |
| 13 | + private static extern int Access(string path, int mode); |
61 | 14 |
|
62 |
| - // It's a symlink, we need to get the target file's mode |
| 15 | + private const int X_OK = 1; |
63 | 16 |
|
64 |
| - int ret; |
65 |
| - FileStatus target; |
66 |
| - while ((ret = FileInterop.Stat(path, out target)) < 0); |
67 |
| - |
68 |
| - if (ret == 0) |
69 |
| - _status.st_mode = FileTypes.S_IFLNK | (target.st_mode & (int)ValidUnixFileModes); |
70 |
| - else |
71 |
| - throw new InvalidOperationException($"Stat failed for {path}"); |
72 |
| - } |
73 |
| - |
74 |
| - private uint FileTypeCode => _status.st_mode & FileTypes.S_IFMT; |
75 |
| - |
76 |
| - public FilePermissions FilePermissions => |
77 |
| - (FilePermissions)(_status.st_mode & (int)ValidUnixFileModes); |
78 |
| - |
79 |
| - public bool IsDirectory => FileTypeCode == FileTypes.S_IFDIR; |
80 |
| - |
81 |
| - internal const FilePermissions ValidUnixFileModes = |
82 |
| - FilePermissions.UserRead | |
83 |
| - FilePermissions.UserWrite | |
84 |
| - FilePermissions.UserExecute | |
85 |
| - FilePermissions.GroupRead | |
86 |
| - FilePermissions.GroupWrite | |
87 |
| - FilePermissions.GroupExecute | |
88 |
| - FilePermissions.OtherRead | |
89 |
| - FilePermissions.OtherWrite | |
90 |
| - FilePermissions.OtherExecute | |
91 |
| - FilePermissions.StickyBit | |
92 |
| - FilePermissions.SetGroup | |
93 |
| - FilePermissions.SetUser; |
94 |
| -} |
95 |
| - |
96 |
| -public static class FileSystemUtil |
97 |
| -{ |
98 |
| - public static FilePermissions ExecutablePermissions => |
99 |
| - FilePermissions.UserExecute |
100 |
| - | FilePermissions.GroupExecute |
101 |
| - | FilePermissions.OtherExecute; |
102 |
| - |
103 |
| - public static bool CheckUnixFilePermissions(string path, FilePermissions permissions) |
| 17 | + public static bool IsUnixFileExecutable(string path) |
104 | 18 | {
|
105 |
| - try |
106 |
| - { |
107 |
| - // if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) |
108 |
| - // return true; // TODO[#840]: Proper executable check for MacOS |
109 |
| - |
110 |
| - var info = new UnixFileInfo(Path.GetFullPath(path)); |
111 |
| - return (info.FilePermissions & permissions) != 0 && !info.IsDirectory; |
112 |
| - } |
113 |
| - catch (Exception ex) |
114 |
| - { |
115 |
| - Console.WriteLine("Error checking file permissions: " + ex.Message); |
116 |
| - return false; |
117 |
| - } |
| 19 | + if (Directory.Exists(path)) return false; |
| 20 | + return Access(Path.GetFullPath(path), X_OK) == 0; |
118 | 21 | }
|
119 | 22 | }
|
0 commit comments