Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cesium.Sdk.Tests/Cesium.Sdk.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ SPDX-License-Identifier: MIT
<ItemGroup>
<PackageReference Include="MedallionShell" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="TruePath.SystemIo" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio" >
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
85 changes: 85 additions & 0 deletions Cesium.Sdk.Tests/FileUtilTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// SPDX-FileCopyrightText: 2025 Cesium contributors <https://github.com/ForNeVeR/Cesium>
//
// SPDX-License-Identifier: MIT

using System.Runtime.InteropServices;
using TruePath;
using TruePath.SystemIo;

namespace Cesium.Sdk.Tests;

public class FileUtilTests
{
private static void CreateUnixFile(AbsolutePath file, AbsolutePath? link = null, UnixFileMode? mode = null)
{
file.WriteAllText("empty");

if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux) &&
!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) return;
if (mode is { } m)
File.SetUnixFileMode(file.Value, m);
if (link is { } linkFile)
{
linkFile.Delete();
File.CreateSymbolicLink(linkFile.Value, file.Value);
}
}

private AbsolutePath TestFile = Temporary.CreateTempFile();
private AbsolutePath TestLink = Temporary.CreateTempFile();

[Fact]
public void ExecutablePermissionsCheckOnUnix()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Assert.True(true);
else
{
var file = TestFile;
CreateUnixFile(file, mode: UnixFileMode.UserExecute);

Assert.True(FileSystemUtil.IsUnixFileExecutable(file.Value));
}
}

[Fact]
public void ExecutableLinkPermissionsCheckOnUnix()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Assert.True(true);
else
{
var file = TestFile;
var link = TestLink;
CreateUnixFile(file, link: link, mode: UnixFileMode.UserExecute);

Assert.True(FileSystemUtil.IsUnixFileExecutable(link.Value));
}
}

[Fact]
public void NoExecutablePermissionsCheckOnUnix()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Assert.True(true);
else
{
var file = TestFile;
CreateUnixFile(file, mode: UnixFileMode.UserRead | UnixFileMode.UserWrite);

Assert.False(FileSystemUtil.IsUnixFileExecutable(file.Value));
}
}

[Fact]
public void InvalidForDirOnUnix()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Assert.True(true);
else
{
var dir = "/etc";
Assert.False(FileSystemUtil.IsUnixFileExecutable(dir));
}
}
}
1 change: 1 addition & 0 deletions Cesium.Sdk/Cesium.Sdk.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ SPDX-License-Identifier: MIT
<Content Include="Sdk\Sdk.props" PackagePath="Sdk\Sdk.props" />
<Content Include="Sdk\Sdk.targets" PackagePath="Sdk\Sdk.targets" />
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="tools" Visible="false"/>
<InternalsVisibleTo Include="Cesium.Sdk.Tests" />
</ItemGroup>

<ItemGroup>
Expand Down
16 changes: 7 additions & 9 deletions Cesium.Sdk/CesiumCompile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,11 @@ private static bool ExecutableFileExists(string path)
var pathExtWithDot = new Lazy<string[]>(() =>
Environment.GetEnvironmentVariable("PATHEXT")?.Split(Path.PathSeparator) ?? []);

if (IsExecutable(path)) return true;
if (File.Exists(path) && IsExecutable(path)) return true;

foreach (var pathEntry in Environment.GetEnvironmentVariable("PATH")?.Split(Path.PathSeparator) ?? [])
{
var fullPath = Path.Combine(pathEntry, pathEntry);
var fullPath = Path.Combine(pathEntry, path);
if (IsExecutable(fullPath)) return true;

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Expand All @@ -305,14 +305,12 @@ private static bool ExecutableFileExists(string path)

bool IsExecutable(string exePath)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var extension = Path.GetExtension(exePath);
return pathExtWithDot.Value.Contains(extension);
}

return true; // TODO[#840]: Proper executable check for Unix
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
|| RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
return FileSystemUtil.IsUnixFileExecutable(exePath);

var extension = Path.GetExtension(exePath);
return pathExtWithDot.Value.Contains(extension);
}
}

Expand Down
22 changes: 22 additions & 0 deletions Cesium.Sdk/FileSystemUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-FileCopyrightText: 2025 Cesium contributors <https://github.com/ForNeVeR/Cesium>
//
// SPDX-License-Identifier: MIT

using System.IO;
using System.Runtime.InteropServices;

namespace Cesium.Sdk;

internal static class FileSystemUtil
{
[DllImport("libc", EntryPoint = "access", SetLastError = true)]
private static extern int Access(string path, int mode);

private const int X_OK = 1;

public static bool IsUnixFileExecutable(string path)
{
if (Directory.Exists(path)) return false;
return Access(Path.GetFullPath(path), X_OK) == 0;
}
}
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ SPDX-License-Identifier: MIT
<PackageVersion Include="QuikGraph" Version="2.5.0" />
<PackageVersion Include="QuikGraph.Graphviz" Version="2.5.0" />
<PackageVersion Include="TruePath" Version="1.10.0" />
<PackageVersion Include="TruePath.SystemIo" Version="1.10.0" />
<PackageVersion Include="Verify.Xunit" Version="31.0.0" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.assert" Version="2.9.3" />
Expand Down
Loading