From 9fcf2dc9844977c47069bc59195c5f76412ab719 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 17 Sep 2025 08:25:09 +0000 Subject: [PATCH 1/5] Initial plan From f53fc0a8380763da595b5a4715c85d272dda0098 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 17 Sep 2025 08:40:24 +0000 Subject: [PATCH 2/5] Add macOS platform support to C# codebase Co-authored-by: peters <869+peters@users.noreply.github.com> --- bootstrap.ps1 | 8 +- build.ps1 | 2 + src/Directory.Build.props | 10 +- src/Snap.CoreRun.Pal/CMakeLists.txt | 12 +- src/Snap.CoreRun.Pal/src/include/pal/pal.hpp | 23 ++ src/Snap.CoreRun.Pal/src/pal.cpp | 25 +- .../Snap.Installer.Tests.csproj | 2 +- src/Snap.Installer/Snap.Installer.csproj | 4 +- .../Snap.Shared.Tests.csproj | 2 +- src/Snap.Tests/Snap.Tests.csproj | 2 +- src/Snap/AnyOS/MacOS/SnapOS.MacOS.cs | 269 ++++++++++++++++++ src/Snap/AnyOS/SnapOs.cs | 13 +- src/Snap/AnyOS/SnapOsSpecialFolders.cs | 16 ++ src/Snap/Snap.csproj | 2 +- src/Snapx.Tests/Snapx.Tests.csproj | 2 +- src/Snapx/Snapx.csproj | 2 +- 16 files changed, 378 insertions(+), 16 deletions(-) create mode 100644 src/Snap/AnyOS/MacOS/SnapOS.MacOS.cs diff --git a/bootstrap.ps1 b/bootstrap.ps1 index 8f676f54..6b77e482 100644 --- a/bootstrap.ps1 +++ b/bootstrap.ps1 @@ -7,7 +7,7 @@ param( [Parameter(Position = 2, ValueFromPipelineByPropertyName = $true)] [switch] $Lto, [Parameter(Position = 3, ValueFromPipelineByPropertyName = $true)] - [ValidateSet("win-x86", "win-x64", "linux-x64", "linux-arm64")] + [ValidateSet("win-x86", "win-x64", "linux-x64", "linux-arm64", "osx-x64", "osx-arm64")] [string] $Rid = $null, [Parameter(Position = 4, ValueFromPipelineByPropertyName = $true, Mandatory = $true)] [string] $NetCoreAppVersion, @@ -211,6 +211,12 @@ function Invoke-Build-Snap-Installer { "linux-arm64" { $SnapInstallerExeName = "Snap.Installer" } + "osx-x64" { + $SnapInstallerExeName = "Snap.Installer" + } + "osx-arm64" { + $SnapInstallerExeName = "Snap.Installer" + } default { Write-Error "Rid not supported: $Rid" } diff --git a/build.ps1 b/build.ps1 index a6d5d52a..9776aca7 100644 --- a/build.ps1 +++ b/build.ps1 @@ -95,6 +95,8 @@ function Invoke-Build-Rids-Array { if($Rid -eq "any") { $Rids += "linux-x64" $Rids += "linux-arm64" + $Rids += "osx-x64" + $Rids += "osx-arm64" } else { $Rids += $Rid } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 7718e01d..28799a82 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -73,7 +73,15 @@ - $(DefineConstants);PLATFORM_MAXOSX; + $(DefineConstants);PLATFORM_MACOSX; + + + + $(DefineConstants);PLATFORM_MACOSX_X64; + + + + $(DefineConstants);PLATFORM_MACOSX_ARM64; diff --git a/src/Snap.CoreRun.Pal/CMakeLists.txt b/src/Snap.CoreRun.Pal/CMakeLists.txt index d56ba279..0c75d970 100644 --- a/src/Snap.CoreRun.Pal/CMakeLists.txt +++ b/src/Snap.CoreRun.Pal/CMakeLists.txt @@ -82,9 +82,15 @@ elseif(UNIX) libstdc++.a ) - list(APPEND pal_DEFINES - PAL_PLATFORM_LINUX - ) + if(APPLE) + list(APPEND pal_DEFINES + PAL_PLATFORM_MACOS + ) + else() + list(APPEND pal_DEFINES + PAL_PLATFORM_LINUX + ) + endif() endif() diff --git a/src/Snap.CoreRun.Pal/src/include/pal/pal.hpp b/src/Snap.CoreRun.Pal/src/include/pal/pal.hpp index 1fe4a73a..9effc9e6 100644 --- a/src/Snap.CoreRun.Pal/src/include/pal/pal.hpp +++ b/src/Snap.CoreRun.Pal/src/include/pal/pal.hpp @@ -52,6 +52,24 @@ #define PAL_API #define PAL_CALLING_CONVENTION #endif +#elif PAL_PLATFORM_MACOS +#include +#include +#include +#include +#include // mode_t +#define PAL_MAX_PATH PATH_MAX +#define PAL_DIRECTORY_SEPARATOR_STR "/" +#define PAL_DIRECTORY_SEPARATOR_C '/' +#define PAL_CORECLR_TPA_SEPARATOR_STR ":" +#define PAL_CORECLR_TPA_SEPARATOR_C ':' +#if defined(__GNUC__) +#define PAL_API __attribute__((visibility("default"))) +#define PAL_CALLING_CONVENTION +#else +#define PAL_API +#define PAL_CALLING_CONVENTION +#endif #else #error Unsupported platform #endif @@ -78,6 +96,10 @@ typedef DWORD pal_exit_code_t; typedef pid_t pal_pid_t; typedef mode_t pal_mode_t; typedef int pal_exit_code_t; +#elif defined(PAL_PLATFORM_MACOS) +typedef pid_t pal_pid_t; +typedef mode_t pal_mode_t; +typedef int pal_exit_code_t; #endif // - Callbacks @@ -112,6 +134,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows(); PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows_8_or_greater(); PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows_7_or_greater(); PAL_API BOOL PAL_CALLING_CONVENTION pal_is_linux(); +PAL_API BOOL PAL_CALLING_CONVENTION pal_is_macos(); PAL_API BOOL PAL_CALLING_CONVENTION pal_is_unknown_os(); // - Environment diff --git a/src/Snap.CoreRun.Pal/src/pal.cpp b/src/Snap.CoreRun.Pal/src/pal.cpp index 6fe6e822..c2d997af 100644 --- a/src/Snap.CoreRun.Pal/src/pal.cpp +++ b/src/Snap.CoreRun.Pal/src/pal.cpp @@ -20,6 +20,17 @@ #include // kill #include // nanosleep static const char* symlink_entrypoint_executable = "/proc/self/exe"; +#elif defined(PAL_PLATFORM_MACOS) +#include // wait +#include // getcwd +#include // open +#include // opendir +#include // dirname +#include // dlopen +#include // kill +#include // nanosleep +#include // _NSGetExecutablePath +static const char* symlink_entrypoint_executable = nullptr; // macOS uses different approach #endif #include @@ -676,7 +687,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_sleep_ms(const uint32_t milliseconds) #if defined(PAL_PLATFORM_WINDOWS) Sleep(milliseconds); return TRUE; -#elif defined(PAL_PLATFORM_LINUX) +#elif defined(PAL_PLATFORM_LINUX) || defined(PAL_PLATFORM_MACOS) struct timespec ts = { 0 }; ts.tv_sec = milliseconds / 1000; ts.tv_nsec = (milliseconds % 1000) * 1000000; @@ -723,10 +734,20 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_is_linux() #endif } +PAL_API BOOL PAL_CALLING_CONVENTION pal_is_macos() +{ +#if defined(PAL_PLATFORM_MACOS) + return TRUE; +#else + return FALSE; +#endif +} + PAL_API BOOL PAL_CALLING_CONVENTION pal_is_unknown_os() { return pal_is_linux() - || pal_is_windows() ? FALSE : TRUE; + || pal_is_windows() + || pal_is_macos() ? FALSE : TRUE; } // - Environment diff --git a/src/Snap.Installer.Tests/Snap.Installer.Tests.csproj b/src/Snap.Installer.Tests/Snap.Installer.Tests.csproj index 14ea191a..c3f95419 100644 --- a/src/Snap.Installer.Tests/Snap.Installer.Tests.csproj +++ b/src/Snap.Installer.Tests/Snap.Installer.Tests.csproj @@ -5,7 +5,7 @@ false true - net10.0 + net9.0 diff --git a/src/Snap.Installer/Snap.Installer.csproj b/src/Snap.Installer/Snap.Installer.csproj index 0e1b4f32..8b1d5cdb 100644 --- a/src/Snap.Installer/Snap.Installer.csproj +++ b/src/Snap.Installer/Snap.Installer.csproj @@ -7,7 +7,7 @@ Exe Snap.Installer Snap.Installer - net10.0 + net9.0 false false @@ -19,7 +19,7 @@ true - + $(NuGetPackageRoot)avalonia\$(AvaloniaVersion)\build\Avalonia.Build.Tasks.dll true diff --git a/src/Snap.Shared.Tests/Snap.Shared.Tests.csproj b/src/Snap.Shared.Tests/Snap.Shared.Tests.csproj index 6e0bdf22..3c1e630b 100644 --- a/src/Snap.Shared.Tests/Snap.Shared.Tests.csproj +++ b/src/Snap.Shared.Tests/Snap.Shared.Tests.csproj @@ -5,7 +5,7 @@ false false - net8.0;net9.0;net10.0 + net8.0;net9.0 diff --git a/src/Snap.Tests/Snap.Tests.csproj b/src/Snap.Tests/Snap.Tests.csproj index bc214a2f..bf1cc7c5 100644 --- a/src/Snap.Tests/Snap.Tests.csproj +++ b/src/Snap.Tests/Snap.Tests.csproj @@ -5,7 +5,7 @@ false true - net8.0;net9.0;net10.0 + net8.0;net9.0 diff --git a/src/Snap/AnyOS/MacOS/SnapOS.MacOS.cs b/src/Snap/AnyOS/MacOS/SnapOS.MacOS.cs new file mode 100644 index 00000000..1a1faa9d --- /dev/null +++ b/src/Snap/AnyOS/MacOS/SnapOS.MacOS.cs @@ -0,0 +1,269 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Snap.AnyOS.Windows; +using Snap.Core; +using Snap.Extensions; +using Snap.Logging; + +namespace Snap.AnyOS.MacOS; + +// macOS exit signal handler using POSIX signals +internal sealed class SnapOsMacOSExitSignal : ISnapOsExitSignal +{ + public event EventHandler Exit; + + public SnapOsMacOSExitSignal() + { + PosixSignalRegistration.Create(PosixSignal.SIGTERM, _ => OnExitSignalHandler()); + PosixSignalRegistration.Create(PosixSignal.SIGINT, _ => OnExitSignalHandler()); + } + + void OnExitSignalHandler() => Exit?.Invoke(null, EventArgs.Empty); +} + +internal sealed class SnapOsMacOS : ISnapOsImpl +{ + readonly ILog _logger = LogProvider.For(); + + public ISnapOsTaskbar Taskbar => throw new PlatformNotSupportedException("Todo: Implement taskbar progressbar for macOS"); + public OSPlatform OsPlatform => OSPlatform.OSX; + public ISnapFilesystem Filesystem { get; } + public ISnapOsProcessManager OsProcessManager { get; } + public SnapOsDistroType DistroType { get; private set; } = SnapOsDistroType.MacOS; + public ISnapOsSpecialFolders SpecialFolders { get; } + public string Username { get; private set; } + + public SnapOsMacOS([NotNull] ISnapFilesystem filesystem, ISnapOsProcessManager snapOsProcessManager, + [NotNull] ISnapOsSpecialFolders snapOsSpecialFolders) + { + SpecialFolders = snapOsSpecialFolders ?? throw new ArgumentNullException(nameof(snapOsSpecialFolders)); + OsProcessManager = snapOsProcessManager; + Filesystem = filesystem ?? throw new ArgumentNullException(nameof(filesystem)); + + SnapOsMacOSInit(); + } + + void SnapOsMacOSInit() + { + Username = Environment.UserName; + + if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + throw new PlatformNotSupportedException(); + } + + DistroType = SnapOsDistroType.MacOS; + } + + public async Task CreateShortcutsForExecutableAsync(SnapOsShortcutDescription shortcutDescription, ILog logger = null, + CancellationToken cancellationToken = default) + { + if (shortcutDescription == null) throw new ArgumentNullException(nameof(shortcutDescription)); + var exeName = Filesystem.PathGetFileName(shortcutDescription.ExeAbsolutePath); + if (Username == null) + { + _logger?.Error($"Unable to create shortcut because username is null. Executable: {exeName}"); + return; + } + + logger?.Info($"Creating shortcuts for executable: {shortcutDescription.ExeAbsolutePath}"); + + var autoStartEnabled = shortcutDescription.ShortcutLocations.HasFlag(SnapShortcutLocation.Startup); + var desktopEnabled = shortcutDescription.ShortcutLocations.HasFlag(SnapShortcutLocation.Desktop); + var startMenuEnabled = shortcutDescription.ShortcutLocations.HasFlag(SnapShortcutLocation.StartMenu); + + // Create .app bundle for desktop and applications + if (desktopEnabled || startMenuEnabled) + { + await CreateMacOSAppBundle(shortcutDescription, logger, cancellationToken); + } + + // Create LaunchAgent plist for startup + if (autoStartEnabled) + { + await CreateLaunchAgentPlist(shortcutDescription, logger, cancellationToken); + } + } + + async Task CreateMacOSAppBundle(SnapOsShortcutDescription shortcutDescription, ILog logger, CancellationToken cancellationToken) + { + var appName = shortcutDescription.SnapApp.Id; + var appBundleName = $"{appName}.app"; + var applicationsDir = "/Applications"; + var appBundlePath = Filesystem.PathCombine(applicationsDir, appBundleName); + var contentsDir = Filesystem.PathCombine(appBundlePath, "Contents"); + var macOSDir = Filesystem.PathCombine(contentsDir, "MacOS"); + var resourcesDir = Filesystem.PathCombine(contentsDir, "Resources"); + + logger?.Info($"Creating macOS app bundle: {appBundlePath}"); + + // Create app bundle structure + Filesystem.DirectoryCreateIfNotExists(appBundlePath); + Filesystem.DirectoryCreateIfNotExists(contentsDir); + Filesystem.DirectoryCreateIfNotExists(macOSDir); + Filesystem.DirectoryCreateIfNotExists(resourcesDir); + + // Create Info.plist + var infoPlistContent = BuildInfoPlist(shortcutDescription); + var infoPlistPath = Filesystem.PathCombine(contentsDir, "Info.plist"); + await Filesystem.FileWriteUtf8StringAsync(infoPlistContent, infoPlistPath, cancellationToken); + + // Create executable launcher script + var launcherScript = BuildLauncherScript(shortcutDescription); + var launcherPath = Filesystem.PathCombine(macOSDir, appName); + await Filesystem.FileWriteUtf8StringAsync(launcherScript, launcherPath, cancellationToken); + + // Make launcher executable + await OsProcessManager.ChmodExecuteAsync(launcherPath, cancellationToken); + + // Copy icon if available + if (!string.IsNullOrWhiteSpace(shortcutDescription.IconAbsolutePath) && + Filesystem.FileExists(shortcutDescription.IconAbsolutePath)) + { + var iconName = $"{appName}.icns"; + var iconPath = Filesystem.PathCombine(resourcesDir, iconName); + try + { + await Filesystem.FileCopyAsync(shortcutDescription.IconAbsolutePath, iconPath, cancellationToken, overwrite: true); + logger?.Info($"Copied icon to: {iconPath}"); + } + catch (Exception ex) + { + logger?.Warn($"Failed to copy icon: {ex.Message}"); + } + } + } + + async Task CreateLaunchAgentPlist(SnapOsShortcutDescription shortcutDescription, ILog logger, CancellationToken cancellationToken) + { + var launchAgentsDir = Filesystem.PathCombine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + "Library", "LaunchAgents"); + var plistName = $"com.snapx.{shortcutDescription.SnapApp.Id}.plist"; + var plistPath = Filesystem.PathCombine(launchAgentsDir, plistName); + + logger?.Info($"Creating LaunchAgent plist: {plistPath}"); + + Filesystem.DirectoryCreateIfNotExists(launchAgentsDir); + + var plistContent = BuildLaunchAgentPlist(shortcutDescription); + await Filesystem.FileWriteUtf8StringAsync(plistContent, plistPath, cancellationToken); + + logger?.Info($"LaunchAgent plist created successfully"); + } + + public bool EnsureConsole() + { + return false; // macOS Terminal handles this + } + + public List GetProcesses() + { + var processes = Process.GetProcesses().Select(process => OsProcessManager.Build(process.Id, process.ProcessName)).ToList(); + return processes; + } + + public ISnapOsExitSignal InstallExitSignalHandler() + { + return new SnapOsMacOSExitSignal(); + } + + string BuildInfoPlist(SnapOsShortcutDescription shortcutDescription) + { + var appName = shortcutDescription.SnapApp.Id; + var version = shortcutDescription.SnapApp.Version.ToString(); + var description = shortcutDescription.NuspecReader.GetDescription(); + + return $@" + + + + CFBundleExecutable + {appName} + CFBundleIdentifier + com.snapx.{appName} + CFBundleName + {appName} + CFBundleVersion + {version} + CFBundleShortVersionString + {version} + CFBundlePackageType + APPL + CFBundleIconFile + {appName}.icns + CFBundleInfoDictionaryVersion + 6.0 + LSMinimumSystemVersion + 10.15 + NSHighResolutionCapable + + +"; + } + + string BuildLauncherScript(SnapOsShortcutDescription shortcutDescription) + { + var workingDirectory = Filesystem.PathGetDirectoryName(shortcutDescription.ExeAbsolutePath); + var environmentVariables = new List(); + + foreach (var (name, value) in shortcutDescription.Environment) + { + environmentVariables.Add($"export {name}=\"{value}\""); + } + + var envVarsString = environmentVariables.Count > 0 ? + string.Join("\n", environmentVariables) + "\n" : ""; + + return $@"#!/bin/bash +{envVarsString} +cd ""{workingDirectory}"" +exec ""{shortcutDescription.ExeAbsolutePath}"" +"; + } + + string BuildLaunchAgentPlist(SnapOsShortcutDescription shortcutDescription) + { + var appName = shortcutDescription.SnapApp.Id; + var workingDirectory = Filesystem.PathGetDirectoryName(shortcutDescription.ExeAbsolutePath); + + var environmentDict = ""; + if (shortcutDescription.Environment.Count > 0) + { + var envEntries = shortcutDescription.Environment + .Select(kv => $@" {kv.Key} + {kv.Value}"); + environmentDict = $@" EnvironmentVariables + +{string.Join("\n", envEntries)} + "; + } + + return $@" + + + + Label + com.snapx.{appName} + ProgramArguments + + {shortcutDescription.ExeAbsolutePath} + + WorkingDirectory + {workingDirectory} + RunAtLoad + + KeepAlive + +{environmentDict} + +"; + } +} \ No newline at end of file diff --git a/src/Snap/AnyOS/SnapOs.cs b/src/Snap/AnyOS/SnapOs.cs index e00be1b7..419a0c11 100644 --- a/src/Snap/AnyOS/SnapOs.cs +++ b/src/Snap/AnyOS/SnapOs.cs @@ -8,6 +8,7 @@ using JetBrains.Annotations; using Snap.AnyOS.Unix; using Snap.AnyOS.Windows; +using Snap.AnyOS.MacOS; using Snap.Core; using Snap.Logging; @@ -23,7 +24,8 @@ public enum SnapOsDistroType Unknown, Windows, Ubuntu, - RaspberryPi + RaspberryPi, + MacOS } internal interface ISnapOs @@ -81,6 +83,11 @@ internal static ISnapOs AnyOs return new SnapOs(new SnapOsUnix(snapFilesystem, snapProcess, snapSpecialFolders)); } + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return new SnapOs(new SnapOsMacOS(snapFilesystem, snapProcess, snapSpecialFolders)); + } + throw new PlatformNotSupportedException(); } } @@ -109,6 +116,10 @@ public SnapOs(ISnapFilesystem snapFilesystem, ISnapOsProcessManager snapOsProces { OsImpl = new SnapOsUnix(snapFilesystem, snapOsProcessManager, isUnitTest ? (ISnapOsSpecialFolders) new SnapOsSpecialFoldersUnitTest(snapFilesystem, workingDirectory) : new SnapOsSpecialFoldersUnix()); + } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + OsImpl = new SnapOsMacOS(snapFilesystem, snapOsProcessManager, isUnitTest ? + (ISnapOsSpecialFolders) new SnapOsSpecialFoldersUnitTest(snapFilesystem, workingDirectory) : new SnapOsSpecialFoldersMacOS()); } else { diff --git a/src/Snap/AnyOS/SnapOsSpecialFolders.cs b/src/Snap/AnyOS/SnapOsSpecialFolders.cs index 37f0e9ef..f3a86bb1 100644 --- a/src/Snap/AnyOS/SnapOsSpecialFolders.cs +++ b/src/Snap/AnyOS/SnapOsSpecialFolders.cs @@ -42,6 +42,11 @@ public static ISnapOsSpecialFolders AnyOs return new SnapOsSpecialFoldersUnix(); } + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return new SnapOsSpecialFoldersMacOS(); + } + throw new PlatformNotSupportedException(); } } @@ -69,6 +74,17 @@ internal sealed class SnapOsSpecialFoldersUnix : SnapOsSpecialFolders public override string NugetCacheDirectory => $"{InstallerCacheDirectory}/temp/nuget"; } +internal sealed class SnapOsSpecialFoldersMacOS : SnapOsSpecialFolders +{ + public override string ApplicationData { get; } = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + public override string LocalApplicationData { get; } = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + public override string DesktopDirectory { get; } = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); + public override string StartupDirectory => $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/Library/LaunchAgents"; + public override string StartMenu => "/Applications"; + public override string InstallerCacheDirectory => $"{ApplicationData}/snapx"; + public override string NugetCacheDirectory => $"{InstallerCacheDirectory}/temp/nuget"; +} + internal sealed class SnapOsSpecialFoldersUnitTest : SnapOsSpecialFolders, IAsyncDisposable { readonly ISnapFilesystem _snapFilesystem; diff --git a/src/Snap/Snap.csproj b/src/Snap/Snap.csproj index 5283bf3d..4ef2c280 100644 --- a/src/Snap/Snap.csproj +++ b/src/Snap/Snap.csproj @@ -8,7 +8,7 @@ true true true - net8.0;net9.0;net10.0 + net8.0;net9.0 true false diff --git a/src/Snapx.Tests/Snapx.Tests.csproj b/src/Snapx.Tests/Snapx.Tests.csproj index 252f33b8..0ea4b0f8 100644 --- a/src/Snapx.Tests/Snapx.Tests.csproj +++ b/src/Snapx.Tests/Snapx.Tests.csproj @@ -5,7 +5,7 @@ false true - net10.0 + net9.0 diff --git a/src/Snapx/Snapx.csproj b/src/Snapx/Snapx.csproj index 978408ed..c32b01b0 100644 --- a/src/Snapx/Snapx.csproj +++ b/src/Snapx/Snapx.csproj @@ -11,7 +11,7 @@ true snapx true - net10.0 + net9.0 true false tools/$(TargetFramework)/any From 0c2f06756c3251804f886ea10f4b0e7757352e54 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 17 Sep 2025 08:43:11 +0000 Subject: [PATCH 3/5] Add macOS native library support and unit tests Co-authored-by: peters <869+peters@users.noreply.github.com> --- .../AnyOS/MacOS/SnapOsMacOSTests.cs | 78 ++++++++++++++++ .../MacOS/SnapOsSpecialFoldersMacOSTests.cs | 48 ++++++++++ src/Snap/Snap.csproj | 92 +++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 src/Snap.Tests/AnyOS/MacOS/SnapOsMacOSTests.cs create mode 100644 src/Snap.Tests/AnyOS/MacOS/SnapOsSpecialFoldersMacOSTests.cs diff --git a/src/Snap.Tests/AnyOS/MacOS/SnapOsMacOSTests.cs b/src/Snap.Tests/AnyOS/MacOS/SnapOsMacOSTests.cs new file mode 100644 index 00000000..9b6b4bd5 --- /dev/null +++ b/src/Snap.Tests/AnyOS/MacOS/SnapOsMacOSTests.cs @@ -0,0 +1,78 @@ +#if PLATFORM_MACOSX +using Snap.AnyOS; +using Snap.AnyOS.MacOS; +using Snap.Core; +using Snap.Shared.Tests; +using Xunit; + +namespace Snap.Tests.AnyOS.MacOS +{ + public class SnapOsMacOSTests : IClassFixture + { + readonly BaseFixture _baseFixture; + readonly ISnapFilesystem _snapFilesystem; + readonly ISnapOs _snapOs; + readonly SnapOsMacOS _snapOsMacOS; + + public SnapOsMacOSTests(BaseFixture baseFixture) + { + _baseFixture = baseFixture; + _snapFilesystem = new SnapFilesystem(); + _snapOsMacOS = new SnapOsMacOS(_snapFilesystem, new SnapOsProcessManager(), new SnapOsSpecialFoldersMacOS()); + _snapOs = new SnapOs(_snapOsMacOS); + } + + [Fact] + public void TestOsPlatform() + { + Assert.Equal(System.Runtime.InteropServices.OSPlatform.OSX, _snapOs.OsPlatform); + } + + [Fact] + public void TestDistroType() + { + Assert.Equal(SnapOsDistroType.MacOS, _snapOs.DistroType); + } + + [Fact] + public void TestSpecialFolders() + { + var specialFolders = _snapOs.SpecialFolders; + + Assert.NotNull(specialFolders.ApplicationData); + Assert.NotNull(specialFolders.LocalApplicationData); + Assert.NotNull(specialFolders.DesktopDirectory); + Assert.NotNull(specialFolders.StartupDirectory); + Assert.NotNull(specialFolders.StartMenu); + Assert.NotNull(specialFolders.InstallerCacheDirectory); + Assert.NotNull(specialFolders.NugetCacheDirectory); + + // macOS-specific path checks + Assert.Contains("Library/LaunchAgents", specialFolders.StartupDirectory); + Assert.Equal("/Applications", specialFolders.StartMenu); + Assert.Contains("snapx", specialFolders.InstallerCacheDirectory); + } + + [Fact] + public void TestGetProcesses() + { + var processes = _snapOs.GetProcesses(); + Assert.NotEmpty(processes); + } + + [Fact] + public void TestUsername() + { + Assert.NotNull(_snapOsMacOS.Username); + Assert.NotEmpty(_snapOsMacOS.Username); + } + + [Fact] + public void TestExitSignalHandler() + { + var exitSignalHandler = _snapOsMacOS.InstallExitSignalHandler(); + Assert.NotNull(exitSignalHandler); + } + } +} +#endif \ No newline at end of file diff --git a/src/Snap.Tests/AnyOS/MacOS/SnapOsSpecialFoldersMacOSTests.cs b/src/Snap.Tests/AnyOS/MacOS/SnapOsSpecialFoldersMacOSTests.cs new file mode 100644 index 00000000..6a8afb04 --- /dev/null +++ b/src/Snap.Tests/AnyOS/MacOS/SnapOsSpecialFoldersMacOSTests.cs @@ -0,0 +1,48 @@ +#if PLATFORM_MACOSX +using Snap.AnyOS; +using Snap.Shared.Tests; +using Xunit; + +namespace Snap.Tests.AnyOS.MacOS +{ + public class SnapOsSpecialFoldersMacOSTests : IClassFixture + { + readonly BaseFixture _baseFixture; + + public SnapOsSpecialFoldersMacOSTests(BaseFixture baseFixture) + { + _baseFixture = baseFixture; + } + + [Fact] + public void TestMacOSSpecialFolders() + { + var specialFolders = new SnapOsSpecialFoldersMacOS(); + + Assert.NotNull(specialFolders.ApplicationData); + Assert.NotNull(specialFolders.LocalApplicationData); + Assert.NotNull(specialFolders.DesktopDirectory); + Assert.NotNull(specialFolders.StartupDirectory); + Assert.NotNull(specialFolders.StartMenu); + Assert.NotNull(specialFolders.InstallerCacheDirectory); + Assert.NotNull(specialFolders.NugetCacheDirectory); + + // Test macOS-specific paths + Assert.Contains("Library/LaunchAgents", specialFolders.StartupDirectory); + Assert.Equal("/Applications", specialFolders.StartMenu); + Assert.Contains("/snapx", specialFolders.InstallerCacheDirectory); + Assert.Contains("/temp/nuget", specialFolders.NugetCacheDirectory); + } + + [Fact] + public void TestAnyOsReturnsMacOSOnMacOS() + { + if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX)) + { + var anyOs = SnapOsSpecialFolders.AnyOs; + Assert.IsType(anyOs); + } + } + } +} +#endif \ No newline at end of file diff --git a/src/Snap/Snap.csproj b/src/Snap/Snap.csproj index 4ef2c280..5ec5f6b1 100644 --- a/src/Snap/Snap.csproj +++ b/src/Snap/Snap.csproj @@ -101,6 +101,7 @@ + PreserveNewest PreserveNewest @@ -116,6 +117,23 @@ PreserveNewest true + + + + PreserveNewest + PreserveNewest + true + + + PreserveNewest + PreserveNewest + true + + + PreserveNewest + PreserveNewest + true + @@ -155,4 +173,78 @@ + + + + + PreserveNewest + PreserveNewest + true + + + PreserveNewest + PreserveNewest + true + + + PreserveNewest + PreserveNewest + true + + + + + PreserveNewest + PreserveNewest + true + + + PreserveNewest + PreserveNewest + true + + + PreserveNewest + PreserveNewest + true + + + + + + PreserveNewest + PreserveNewest + true + + + PreserveNewest + PreserveNewest + true + + + PreserveNewest + PreserveNewest + true + + + + + + PreserveNewest + PreserveNewest + true + + + PreserveNewest + PreserveNewest + true + + + PreserveNewest + PreserveNewest + true + + + + From 2e66342e990e7c80268f4da288633e5b7f03a128 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 19 Sep 2025 09:51:24 +0000 Subject: [PATCH 4/5] Merge develop branch - resolve conflicts for macOS support Co-authored-by: peters <869+peters@users.noreply.github.com> --- .github/workflows/dotnetcore.yml | 63 +- .gitmodules | 5 +- AGENTS.md | 2 +- README.md | 2 +- build.ps1 | 41 +- docker/Dockerfile | 6 +- dotnet-tools.json | 13 + src/CMakeLists.txt | 1 - src/Directory.Build.props | 8 + src/Snap.CoreRun.Pal/CMakeLists.txt | 48 +- src/Snap.CoreRun.Pal/src/include/pal/pal.hpp | 126 +- .../src/include/pal/pal_module.hpp | 32 +- .../src/include/pal/pal_semaphore.hpp | 11 +- .../src/include/pal/pal_string.hpp | 179 +-- src/Snap.CoreRun.Pal/src/pal.cpp | 1075 +++++++---------- src/Snap.CoreRun.Pal/src/pal_module.cpp | 31 +- src/Snap.CoreRun.Pal/src/pal_semaphore.cpp | 20 +- src/Snap.CoreRun.Pal/src/pal_string.cpp | 96 +- .../src/vendor/rcedit/rcedit.cpp | 82 +- .../src/vendor/rcedit/rcedit.hpp | 33 +- src/Snap.CoreRun.Pal/test/anyos.cpp | 323 ++--- src/Snap.CoreRun.Pal/test/unix.cpp | 87 +- src/Snap.CoreRun.Pal/test/windows.cpp | 89 +- src/Snap.CoreRun.Tests/CMakeLists.txt | 88 +- .../src/include/tests/support/unique_id.hpp | 44 + .../src/include/tests/support/utils.hpp | 122 +- src/Snap.CoreRun.Tests/src/main.cpp | 5 +- src/Snap.CoreRun/CMakeLists.txt | 32 +- src/Snap.CoreRun/src/corerun.hpp | 39 +- src/Snap.CoreRun/src/main.cpp | 34 +- src/Snap.CoreRun/src/main.hpp | 165 +-- src/Snap.CoreRun/src/main_demoapp.cpp | 56 +- src/Snap.CoreRun/src/resource.h | 2 +- src/Snap.CoreRun/src/stubexecutable.cpp | 89 +- src/Snap.CoreRun/src/stubexecutable.hpp | 12 +- src/Snap.CoreRun/src/targetver.h | 2 +- src/Snap.CoreRun/test/anyos.cpp | 285 ++--- src/Snap/Snap.csproj | 3 - src/Snapx.sln | 77 -- src/Snapx.sln.DotSettings.user | 5 - src/Snapx.slnx | 12 + src/Vendor/bsdiff | 2 +- src/Vendor/nanoid_cpp | 1 - 43 files changed, 1527 insertions(+), 1921 deletions(-) create mode 100644 dotnet-tools.json create mode 100644 src/Snap.CoreRun.Tests/src/include/tests/support/unique_id.hpp delete mode 100644 src/Snapx.sln delete mode 100644 src/Snapx.sln.DotSettings.user create mode 100644 src/Snapx.slnx delete mode 160000 src/Vendor/nanoid_cpp diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index 15ae5d06..d9b6ddeb 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -9,14 +9,7 @@ on: branches: - develop -# NOTE: Remember to update docker images if you update .NET sdks - env: - GITVERSION_VERSION: 6.4.0 - SNAPX_DOTNET_FRAMEWORK_VERSION: net10.0 - DOTNET_NET80_VERSION: 8.0.414 - DOTNET_NET90_VERSION: 9.0.305 - DOTNET_NET100_VERSION: 10.0.100-rc.1.25451.107 DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 DOTNET_NOLOGO: 1 @@ -29,23 +22,52 @@ jobs: runs-on: ubuntu-latest outputs: SNAPX_VERSION: ${{ steps.set-version.outputs.SNAPX_VERSION }} + GITVERSION_VERSION: ${{ steps.read-versions.outputs.GITVERSION_VERSION }} + SNAPX_DOTNET_FRAMEWORK_VERSION: ${{ steps.read-versions.outputs.SNAPX_DOTNET_FRAMEWORK_VERSION }} + DOTNET_NET80_VERSION: ${{ steps.read-versions.outputs.DOTNET_NET80_VERSION }} + DOTNET_NET90_VERSION: ${{ steps.read-versions.outputs.DOTNET_NET90_VERSION }} + DOTNET_NET100_VERSION: ${{ steps.read-versions.outputs.DOTNET_NET100_VERSION }} steps: - name: Checkout uses: actions/checkout@v5 with: fetch-depth: 0 - - name: Add dotnet tools to environment path + - id: read-versions + name: Read version configuration from Directory.Build.props shell: pwsh - run: echo "${HOME}/.dotnet/tools" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + run: | + [xml] $xml_content = Get-Content "./src/Directory.Build.props" + + $gitversion_version = Select-Xml -Xml $xml_content -XPath "//Project/PropertyGroup/GitVersionToolVersion" | Select -Expand Node | Select -Expand "#text" + $snapx_dotnet_framework_version = Select-Xml -Xml $xml_content -XPath "//Project/PropertyGroup/SnapxDotNetFrameworkVersion" | Select -Expand Node | Select -Expand "#text" + $dotnet_net80_version = Select-Xml -Xml $xml_content -XPath "//Project/PropertyGroup/DotNetNet80Version" | Select -Expand Node | Select -Expand "#text" + $dotnet_net90_version = Select-Xml -Xml $xml_content -XPath "//Project/PropertyGroup/DotNetNet90Version" | Select -Expand Node | Select -Expand "#text" + $dotnet_net100_version = Select-Xml -Xml $xml_content -XPath "//Project/PropertyGroup/DotNetNet100Version" | Select -Expand Node | Select -Expand "#text" + + echo "GITVERSION_VERSION=$gitversion_version" >> $env:GITHUB_OUTPUT + echo "SNAPX_DOTNET_FRAMEWORK_VERSION=$snapx_dotnet_framework_version" >> $env:GITHUB_OUTPUT + echo "DOTNET_NET80_VERSION=$dotnet_net80_version" >> $env:GITHUB_OUTPUT + echo "DOTNET_NET90_VERSION=$dotnet_net90_version" >> $env:GITHUB_OUTPUT + echo "DOTNET_NET100_VERSION=$dotnet_net100_version" >> $env:GITHUB_OUTPUT + echo "GITVERSION_VERSION=$gitversion_version" >> $env:GITHUB_ENV + + Write-Host "Read versions from Directory.Build.props:" + Write-Host " GitVersion: $gitversion_version" + Write-Host " .NET Framework: $snapx_dotnet_framework_version" + Write-Host " .NET 8.0: $dotnet_net80_version" + Write-Host " .NET 9.0: $dotnet_net90_version" + Write-Host " .NET 10.0: $dotnet_net100_version" - id: set-version name: Setup GitVersion and set build version - shell: pwsh run: | - dotnet tool update GitVersion.Tool --global --version ${{ env.GITVERSION_VERSION }} - $SNAPX_VERSION = (dotnet gitversion /showVariable SemVer).Trim().ToLowerInvariant() - echo "SNAPX_VERSION=$SNAPX_VERSION" >> $env:GITHUB_OUTPUT + dotnet tool install GitVersion.Tool --global --version ${{ env.GITVERSION_VERSION }} + dotnet tool restore + echo "Testing GitVersion command availability..." + SNAPX_VERSION=$(dotnet gitversion /showVariable SemVer | tr '[:upper:]' '[:lower:]' | xargs) + echo "GitVersion output: '$SNAPX_VERSION'" + echo "SNAPX_VERSION=$SNAPX_VERSION" >> $GITHUB_OUTPUT linux: runs-on: ${{ matrix.os }} @@ -58,6 +80,10 @@ jobs: os: [ubuntu-latest] env: SNAPX_VERSION: ${{ needs.setup.outputs.SNAPX_VERSION }} + SNAPX_DOTNET_FRAMEWORK_VERSION: ${{ needs.setup.outputs.SNAPX_DOTNET_FRAMEWORK_VERSION }} + DOTNET_NET100_VERSION: ${{ needs.setup.outputs.DOTNET_NET100_VERSION }} + DOTNET_NET90_VERSION: ${{ needs.setup.outputs.DOTNET_NET90_VERSION }} + DOTNET_NET80_VERSION: ${{ needs.setup.outputs.DOTNET_NET80_VERSION }} steps: - name: Checkout uses: actions/checkout@v5 @@ -131,6 +157,10 @@ jobs: os: [windows-latest] env: SNAPX_VERSION: ${{ needs.setup.outputs.SNAPX_VERSION }} + SNAPX_DOTNET_FRAMEWORK_VERSION: ${{ needs.setup.outputs.SNAPX_DOTNET_FRAMEWORK_VERSION }} + DOTNET_NET100_VERSION: ${{ needs.setup.outputs.DOTNET_NET100_VERSION }} + DOTNET_NET90_VERSION: ${{ needs.setup.outputs.DOTNET_NET90_VERSION }} + DOTNET_NET80_VERSION: ${{ needs.setup.outputs.DOTNET_NET80_VERSION }} steps: - name: Checkout uses: actions/checkout@v5 @@ -190,6 +220,9 @@ jobs: needs: [setup, windows, linux] # todo: enable me when github actions supports arm64: test-linux-arm64 env: SNAPX_VERSION: ${{ needs.setup.outputs.SNAPX_VERSION }} + DOTNET_NET100_VERSION: ${{ needs.setup.outputs.DOTNET_NET100_VERSION }} + DOTNET_NET90_VERSION: ${{ needs.setup.outputs.DOTNET_NET90_VERSION }} + DOTNET_NET80_VERSION: ${{ needs.setup.outputs.DOTNET_NET80_VERSION }} steps: - name: Checkout uses: actions/checkout@v5 @@ -228,10 +261,6 @@ jobs: ${{ env.DOTNET_NET90_VERSION }} ${{ env.DOTNET_NET80_VERSION }} - - name: Add dotnet tools to environment path - shell: pwsh - run: echo "${HOME}/.dotnet/tools" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - name: Build nupkgs shell: pwsh run: ./build.ps1 -Target Snapx -CIBuild -Version ${{ env.SNAPX_VERSION }} -Configuration Release diff --git a/.gitmodules b/.gitmodules index a5b0aaa7..e117de1c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,9 +7,6 @@ [submodule "src/Vendor/cxxopts"] path = src/Vendor/cxxopts url=https://github.com/jarro2783/cxxopts.git -[submodule "src/Vendor/nanoid_cpp"] - path = src/Vendor/nanoid_cpp - url = https://github.com/mcmikecreations/nanoid_cpp.git [submodule "src/Vendor/bsdiff"] path = src/Vendor/bsdiff - url = https://github.com/fintermobilityas/bsdiff.git + url = https://github.com/fintermobilityas/bsdiff.git \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index ef3e96a8..ee60f7df 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,7 @@ - `src/Snap`, `src/Snapx`, `src/Snap.Installer`: primary .NET projects (library, CLI, and installer). - Native C++ runtime: `src/Snap.CoreRun` (+ tests in `src/Snap.CoreRun.Tests`). - Managed tests: `src/Snap.Tests`, `src/Snapx.Tests`, `src/Snap.Installer.Tests`, shared fixtures in `src/Snap.Shared.Tests`. -- Solution: `src/Snapx.sln`. Build outputs land under `build/` (e.g., `build/dotnet`, `build/native`). +- Solution: `src/Snapx.slnx` (.NET 10 XML format). Build outputs land under `build/` (e.g., `build/dotnet`, `build/native`). - Docs and tooling: `docs/`, `docker/`, PowerShell scripts in repo root. ## Build, Test, and Development Commands diff --git a/README.md b/README.md index b12a6816..2aa0dd89 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ Checkout our sample application, [snapx demoapp](https://github.com/fintermobili #### Bootstrap snapx -Before you can open `src\Snapx.sln` in Visual Studio you must bootstrap dependencies. +Before you can open `src\Snapx.slnx` in Visual Studio you must bootstrap dependencies. Run `init.ps1` and all dependencies will be built in `Debug` and `Release` mode. ## .NET frameworks supported diff --git a/build.ps1 b/build.ps1 index 9776aca7..101bd2a1 100644 --- a/build.ps1 +++ b/build.ps1 @@ -74,6 +74,27 @@ $DockerGithubRegistryUrl = "ghcr.io/fintermobilityas" $SummaryStopwatch = $Stopwatch::StartNew() $SummaryStopwatch.Restart() +function Get-DotNetVersionsFromDirectoryBuildProps { + $DirectoryBuildPropsPath = Join-Path $SrcDirectory "Directory.Build.props" + + if (!(Test-Path $DirectoryBuildPropsPath)) { + Write-Error "Directory.Build.props not found at: $DirectoryBuildPropsPath" + exit 1 + } + + [xml] $xml = Get-Content $DirectoryBuildPropsPath + + $versions = @{ + GitVersionToolVersion = ($xml.SelectSingleNode("//GitVersionToolVersion")).InnerText + SnapxDotNetFrameworkVersion = ($xml.SelectSingleNode("//SnapxDotNetFrameworkVersion")).InnerText + DotNetNet80Version = ($xml.SelectSingleNode("//DotNetNet80Version")).InnerText + DotNetNet90Version = ($xml.SelectSingleNode("//DotNetNet90Version")).InnerText + DotNetNet100Version = ($xml.SelectSingleNode("//DotNetNet100Version")).InnerText + } + + return $versions +} + function Invoke-Build-Rids-Array { param( [Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true)] @@ -374,9 +395,14 @@ function Invoke-Docker "pull $DockerImageSrc" ) } else { + $versions = Get-DotNetVersionsFromDirectoryBuildProps $DockerImageSrc = $DockerImageName Invoke-Command-Colored $CommandDocker @( - "build -f ""${DockerFilenamePath}"" -t $DockerImageName docker" + "build -f ""${DockerFilenamePath}""", + "--build-arg DOTNET_80_SDK_VERSION=$($versions.DotNetNet80Version)", + "--build-arg DOTNET_90_SDK_VERSION=$($versions.DotNetNet90Version)", + "--build-arg DOTNET_100_SDK_VERSION=$($versions.DotNetNet100Version)", + "-t $DockerImageName docker" ) } @@ -526,8 +552,19 @@ switch ($Target) { } } "Publish-Docker-Image" { + $versions = Get-DotNetVersionsFromDirectoryBuildProps + + Write-Host "Building Docker image with versions from Directory.Build.props:" + Write-Host " .NET 8.0: $($versions.DotNetNet80Version)" + Write-Host " .NET 9.0: $($versions.DotNetNet90Version)" + Write-Host " .NET 10.0: $($versions.DotNetNet100Version)" + Invoke-Command-Colored $CommandDocker @( - "build --no-cache -f ""$DockerFilenamePath"" -t ${DockerGithubRegistryUrl}/${DockerImageName}:${DockerVersion} docker" + "build --no-cache -f ""$DockerFilenamePath""", + "--build-arg DOTNET_80_SDK_VERSION=$($versions.DotNetNet80Version)", + "--build-arg DOTNET_90_SDK_VERSION=$($versions.DotNetNet90Version)", + "--build-arg DOTNET_100_SDK_VERSION=$($versions.DotNetNet100Version)", + "-t ${DockerGithubRegistryUrl}/${DockerImageName}:${DockerVersion} docker" ) Invoke-Command-Colored $CommandDocker @( diff --git a/docker/Dockerfile b/docker/Dockerfile index 4aaacb42..e9a10c51 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -3,9 +3,9 @@ FROM ubuntu:20.04 AS env-build ENV DEBIAN_FRONTEND=noninteractive ENV SNAPX_DOCKER_WORKING_DIR /build/snapx -ARG DOTNET_80_SDK_VERSION=8.0.414 -ARG DOTNET_90_SDK_VERSION=9.0.305 -ARG DOTNET_100_SDK_VERSION=10.0.100-rc.1.25451.107 +ARG DOTNET_80_SDK_VERSION +ARG DOTNET_90_SDK_VERSION +ARG DOTNET_100_SDK_VERSION ARG DOTNET_RID=linux-x64 diff --git a/dotnet-tools.json b/dotnet-tools.json new file mode 100644 index 00000000..38d3dc96 --- /dev/null +++ b/dotnet-tools.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "gitversion.tool": { + "version": "6.4.0", + "commands": [ + "dotnet-gitversion" + ], + "rollForward": false + } + } +} \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0fa08baf..514142a3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,7 +32,6 @@ if (BUILD_ENABLE_TESTS) message(STATUS "Unit tests enabled.") add_subdirectory(Vendor/gtest) - add_subdirectory(Vendor/nanoid_cpp) enable_testing() set(GTEST_ALL_CPP_FILENAME ${PROJECT_SOURCE_DIR}/Vendor/gtest/googletest/src/gtest-all.cc) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 28799a82..cf55d83f 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -84,4 +84,12 @@ $(DefineConstants);PLATFORM_MACOSX_ARM64; + + 6.4.0 + net10.0 + 8.0.414 + 9.0.305 + 10.0.100-rc.1.25451.107 + + diff --git a/src/Snap.CoreRun.Pal/CMakeLists.txt b/src/Snap.CoreRun.Pal/CMakeLists.txt index 0c75d970..866e929b 100644 --- a/src/Snap.CoreRun.Pal/CMakeLists.txt +++ b/src/Snap.CoreRun.Pal/CMakeLists.txt @@ -1,86 +1,86 @@ -cmake_minimum_required (VERSION 3.10 FATAL_ERROR) +cmake_minimum_required(VERSION 3.10 FATAL_ERROR) project(pal CXX) # https://github.com/Squirrel/Squirrel.Windows/pull/1444/files function(pal_mitigate_dll_hijacking_for_targets targets) - if(WIN32) + if (WIN32) if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") set(PAL_WIN32_DELAYLOAD_DLLS "user32.dll;advapi32.dll;shell32.dll;ole32.dll;oleaut32.dll;urlmon.dll") set_property(TARGET ${targets} PROPERTY LINK_FLAGS "/DELAYLOAD:${PAL_WIN32_DELAYLOAD_DLLS}") message(STATUS "Dll mitigation enabled for targets: ${targets}") - endif() - else() + endif () + else () message(FATAL_ERROR "Dll hijack mitigation is only supported on Windows") - endif() + endif () endfunction() list(APPEND pal_INCLUDE_DIRS src/include ../Vendor/plog/include - ) +) list(APPEND pal_SOURCES src/pal_string.cpp src/pal_module.cpp src/pal_semaphore.cpp src/pal.cpp - ) +) list(APPEND pal_DEFINES UNICODE _UNICODE PAL_LOGGING_ENABLED - ) +) list(APPEND pal_static_LIBS) -if(WIN32) +if (WIN32) list(APPEND pal_INCLUDE_DIRS src/vendor - ) + ) list(APPEND pal_SOURCES src/vendor/rcedit/rcedit.cpp - ) -endif() + ) +endif () add_library(pal_static STATIC ${pal_SOURCES} - ) +) add_library(pal SHARED ${pal_SOURCES} - ) +) -if(WIN32) +if (WIN32) list(APPEND pal_DEFINES PAL_PLATFORM_WINDOWS _UNICODE UNICODE - ) + ) list(APPEND pal_LIBS shlwapi shell32 kernel32 - ) + ) if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") target_compile_options(pal_static PUBLIC "/MT$<$:d>") - endif() + endif () pal_mitigate_dll_hijacking_for_targets(pal) -elseif(UNIX) +elseif (UNIX) list(APPEND pal_LIBS dl pthread - ) + ) list(APPEND pal_static_LIBS libstdc++.a - ) + ) if(APPLE) list(APPEND pal_DEFINES @@ -92,15 +92,15 @@ elseif(UNIX) ) endif() -endif() +endif () -foreach(cmake_target IN ITEMS pal pal_static) +foreach (cmake_target IN ITEMS pal pal_static) target_include_directories(${cmake_target} PUBLIC ${pal_INCLUDE_DIRS}) target_compile_definitions(${cmake_target} PUBLIC ${pal_DEFINES}) target_link_libraries(${cmake_target} PUBLIC ${pal_LIBS}) set_property(TARGET ${cmake_target} PROPERTY CXX_STANDARD 17) set_property(TARGET ${cmake_target} PROPERTY CXX_STANDARD_REQUIRED ON) set_property(TARGET ${cmake_target} PROPERTY POSITION_INDEPENDENT_CODE ON) -endforeach(cmake_target) +endforeach (cmake_target) target_link_libraries(pal_static PUBLIC ${pal_static_LIBS}) diff --git a/src/Snap.CoreRun.Pal/src/include/pal/pal.hpp b/src/Snap.CoreRun.Pal/src/include/pal/pal.hpp index 9effc9e6..ba37bb35 100644 --- a/src/Snap.CoreRun.Pal/src/include/pal/pal.hpp +++ b/src/Snap.CoreRun.Pal/src/include/pal/pal.hpp @@ -25,8 +25,9 @@ #endif #ifdef PAL_PLATFORM_WINDOWS -#define PAL_MAX_PATH MAX_PATH +#define PAL_MAX_PATH MAX_PATH #define PAL_MAX_PATH_UNICODE (1 << 15) // https://docs.microsoft.com/en-gb/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation + #define PAL_DIRECTORY_SEPARATOR_STR "\\" #define PAL_DIRECTORY_SEPARATOR_WIDE_STR L"\\" #define PAL_DIRECTORY_SEPARATOR_C '\\' @@ -47,9 +48,9 @@ #define PAL_CORECLR_TPA_SEPARATOR_C ':' #if defined(__GNUC__) #define PAL_API __attribute__((visibility("default"))) -#define PAL_CALLING_CONVENTION +#define PAL_CALLING_CONVENTION #else -#define PAL_API +#define PAL_API #define PAL_CALLING_CONVENTION #endif #elif PAL_PLATFORM_MACOS @@ -88,7 +89,7 @@ extern "C" { typedef int BOOL; typedef FILE pal_file_handle_t; -#if defined(PAL_PLATFORM_WINDOWS) +#if defined(PAL_PLATFORM_WINDOWS) typedef DWORD pal_pid_t; typedef int pal_mode_t; typedef DWORD pal_exit_code_t; @@ -104,77 +105,126 @@ typedef int pal_exit_code_t; // - Callbacks -typedef BOOL(*pal_fs_list_filter_callback_t)(const char* filename); +typedef BOOL (*pal_fs_list_filter_callback_t)(const char *filename); // - Generic PAL_API BOOL PAL_CALLING_CONVENTION pal_isdebuggerpresent(); + PAL_API BOOL PAL_CALLING_CONVENTION pal_mitigate_dll_hijacking(); + PAL_API BOOL PAL_CALLING_CONVENTION pal_wait_for_debugger(); -PAL_API BOOL PAL_CALLING_CONVENTION pal_load_library(const char* name_in, BOOL pinning_required, void** instance_out); -PAL_API BOOL PAL_CALLING_CONVENTION pal_free_library(void* instance_in); -PAL_API BOOL PAL_CALLING_CONVENTION pal_getprocaddress(void* instance_in, const char* name_in, void** ptr_out); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_load_library(const char *name_in, BOOL pinning_required, void **instance_out); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_free_library(void *instance_in); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_getprocaddress(void *instance_in, const char *name_in, void **ptr_out); + PAL_API BOOL PAL_CALLING_CONVENTION pal_is_elevated(); -PAL_API BOOL PAL_CALLING_CONVENTION pal_set_icon(const char* filename_in, const char* icon_filename_in); -PAL_API BOOL PAL_CALLING_CONVENTION pal_has_icon(const char * filename_in); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_set_icon(const char *filename_in, const char *icon_filename_in); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_has_icon(const char *filename_in); + PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_real_path(char **real_path_out); + PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_cwd(char **cwd_out); + PAL_API BOOL PAL_CALLING_CONVENTION pal_process_is_running(pal_pid_t pid); + PAL_API BOOL PAL_CALLING_CONVENTION pal_process_kill(pal_pid_t pid); -PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_pid(pal_pid_t* pid_out); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_pid(pal_pid_t * pid_out); + PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_name(char **exe_name_out); + PAL_API BOOL PAL_CALLING_CONVENTION pal_process_exec(const char *filename_in, const char *working_dir_in, int argc_in, char **argv_in, pal_exit_code_t *exit_code_out); -PAL_API BOOL PAL_CALLING_CONVENTION pal_process_daemonize(const char *filename_in, const char *working_dir_in, int argc_in, + +PAL_API BOOL PAL_CALLING_CONVENTION pal_process_daemonize(const char *filename_in, const char *working_dir_in, + int argc_in, char **argv_in, int cmd_show_in /* Only applicable on Windows */, pal_pid_t *pid_out); + PAL_API BOOL PAL_CALLING_CONVENTION pal_sleep_ms(uint32_t milliseconds); + PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows(); + PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows_8_or_greater(); + PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows_7_or_greater(); + PAL_API BOOL PAL_CALLING_CONVENTION pal_is_linux(); PAL_API BOOL PAL_CALLING_CONVENTION pal_is_macos(); + PAL_API BOOL PAL_CALLING_CONVENTION pal_is_unknown_os(); // - Environment -PAL_API BOOL PAL_CALLING_CONVENTION pal_env_set(const char* name_in, const char* value_in); -PAL_API BOOL PAL_CALLING_CONVENTION pal_env_get(const char* environment_variable_in, char** environment_variable_value_out); -PAL_API BOOL PAL_CALLING_CONVENTION pal_env_get_bool(const char* environment_variable_in); -PAL_API BOOL PAL_CALLING_CONVENTION pal_env_expand_str(const char* environment_in, char** environment_out); +PAL_API BOOL PAL_CALLING_CONVENTION pal_env_set(const char *name_in, const char *value_in); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_env_get(const char *environment_variable_in, + char **environment_variable_value_out); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_env_get_bool(const char *environment_variable_in); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_env_expand_str(const char *environment_in, char **environment_out); // - Filesystem -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_chmod(const char* path_in, pal_mode_t mode); -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_directories(const char* path_in, pal_fs_list_filter_callback_t filter_callback_in, - const char* filter_extension_in, char*** directories_out, size_t* directories_out_len); -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_files(const char* path_in, pal_fs_list_filter_callback_t filter_callback_in, - const char* filter_extension_in, char*** files_out, size_t* files_out_len); -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_file_exists(const char* file_path_in); -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_get_cwd(char** working_directory_out); -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_directory_exists(const char* path_in); -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_get_file_size(const char* filename_in, size_t* file_size_out); +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_chmod(const char *path_in, pal_mode_t mode); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_directories(const char *path_in, + pal_fs_list_filter_callback_t filter_callback_in, + const char *filter_extension_in, char ***directories_out, + size_t *directories_out_len); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_files(const char *path_in, + pal_fs_list_filter_callback_t filter_callback_in, + const char *filter_extension_in, char ***files_out, + size_t *files_out_len); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_file_exists(const char *file_path_in); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_get_cwd(char **working_directory_out); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_directory_exists(const char *path_in); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_get_file_size(const char *filename_in, size_t *file_size_out); + PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_read_file(const char *filename_in, char **bytes_out, size_t *bytes_read_out); -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_mkdir(const char* directory_in, pal_mode_t mode_in); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_mkdir(const char *directory_in, pal_mode_t mode_in); + PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_mkdirp(const char *directory_in, pal_mode_t mode_in); -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_rmdir(const char* directory_in, BOOL recursive); -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_rmfile(const char* filename_in); -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_write(const char* filename_in, const char* data_in, size_t data_len_in); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_rmdir(const char *directory_in, BOOL recursive); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_rmfile(const char *filename_in); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_write(const char *filename_in, const char *data_in, size_t data_len_in); // - Path -PAL_API BOOL PAL_CALLING_CONVENTION pal_path_normalize(const char* path_in, char** path_normalized_out); -PAL_API BOOL PAL_CALLING_CONVENTION pal_path_get_directory_name(const char* path_in, char** path_out); -PAL_API BOOL PAL_CALLING_CONVENTION pal_path_get_directory_name_from_file_path(const char * path_in, char ** path_out); -PAL_API BOOL PAL_CALLING_CONVENTION pal_path_combine(const char* path1, const char* path2, char** path_out); +PAL_API BOOL PAL_CALLING_CONVENTION pal_path_normalize(const char *path_in, char **path_normalized_out); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_path_get_directory_name(const char *path_in, char **path_out); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_path_get_directory_name_from_file_path(const char *path_in, char **path_out); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_path_combine(const char *path1, const char *path2, char **path_out); // - String -PAL_API BOOL PAL_CALLING_CONVENTION pal_str_endswith(const char* src, const char* str); -PAL_API BOOL PAL_CALLING_CONVENTION pal_str_startswith(const char* src, const char* str); -PAL_API BOOL PAL_CALLING_CONVENTION pal_str_iequals(const char* lhs, const char* rhs); -PAL_API BOOL PAL_CALLING_CONVENTION pal_str_is_null_or_whitespace(const char* str); +PAL_API BOOL PAL_CALLING_CONVENTION pal_str_endswith(const char *src, const char *str); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_str_startswith(const char *src, const char *str); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_str_iequals(const char *lhs, const char *rhs); + +PAL_API BOOL PAL_CALLING_CONVENTION pal_str_is_null_or_whitespace(const char *str); #ifdef __cplusplus } -#endif +#endif \ No newline at end of file diff --git a/src/Snap.CoreRun.Pal/src/include/pal/pal_module.hpp b/src/Snap.CoreRun.Pal/src/include/pal/pal_module.hpp index 23d4c711..cddac24f 100644 --- a/src/Snap.CoreRun.Pal/src/include/pal/pal_module.hpp +++ b/src/Snap.CoreRun.Pal/src/include/pal/pal_module.hpp @@ -2,26 +2,32 @@ #include -class pal_module final -{ - void* m_module; +class pal_module final { + void *m_module; std::string m_filename; public: - explicit pal_module(const std::string& filename); - pal_module(const pal_module&) noexcept = delete; - pal_module& operator=(const pal_module&) noexcept = delete; - pal_module(pal_module&&) noexcept = delete; - pal_module& operator=(pal_module&&) noexcept = delete; + explicit pal_module(const std::string &filename); + + pal_module(const pal_module &) noexcept = delete; + + pal_module &operator=(const pal_module &) noexcept = delete; + + pal_module(pal_module &&) noexcept = delete; + + pal_module &operator=(pal_module &&) noexcept = delete; + ~pal_module(); [[nodiscard]] bool is_loaded() const; - [[nodiscard]] const std::string& get_filename() const; + + [[nodiscard]] const std::string &get_filename() const; + template - T bind(const std::string& fn) - { + T bind(const std::string &fn) { return reinterpret_cast(_bind(fn)); } + private: - [[nodiscard]] void* _bind(const std::string& fn) const; -}; + [[nodiscard]] void *_bind(const std::string &fn) const; +}; \ No newline at end of file diff --git a/src/Snap.CoreRun.Pal/src/include/pal/pal_semaphore.hpp b/src/Snap.CoreRun.Pal/src/include/pal/pal_semaphore.hpp index 670c2688..9f9a5af7 100644 --- a/src/Snap.CoreRun.Pal/src/include/pal/pal_semaphore.hpp +++ b/src/Snap.CoreRun.Pal/src/include/pal/pal_semaphore.hpp @@ -12,16 +12,19 @@ class pal_semaphore_machine_wide final { private: -#if defined(PAL_PLATFORM_WINDOWS) +#if defined(PAL_PLATFORM_WINDOWS) HANDLE m_semaphore; #elif defined(PAL_PLATFORM_LINUX) - sem_t* m_semaphore; + sem_t *m_semaphore; #endif std::string m_semaphore_name; public: - explicit pal_semaphore_machine_wide(const std::string& name); + explicit pal_semaphore_machine_wide(const std::string &name); + bool try_create(); + bool release(); + ~pal_semaphore_machine_wide(); -}; +}; \ No newline at end of file diff --git a/src/Snap.CoreRun.Pal/src/include/pal/pal_string.hpp b/src/Snap.CoreRun.Pal/src/include/pal/pal_string.hpp index 7aea2df0..e0b6c688 100644 --- a/src/Snap.CoreRun.Pal/src/include/pal/pal_string.hpp +++ b/src/Snap.CoreRun.Pal/src/include/pal/pal_string.hpp @@ -4,27 +4,25 @@ #include #define _strdup strdup #define _wcsdup wcsdup -#elif defined(PAL_PLATFORM_WINDOWS) +#elif defined(PAL_PLATFORM_WINDOWS) #include #include #include // - String internal -wchar_t* pal_str_widen(const char* utf8_str); -char* pal_str_narrow(const wchar_t* utf16_str); +wchar_t *pal_str_widen(const char *utf8_str); +char *pal_str_narrow(const wchar_t *utf16_str); template -class pal_string -{ - TStorageClass* m_ptr; +class pal_string { + TStorageClass *m_ptr; + protected: std::basic_string m_value; public: - virtual ~pal_string() - { - if (m_ptr != nullptr) - { + virtual ~pal_string() { + if (m_ptr != nullptr) { delete m_ptr; m_ptr = nullptr; } @@ -32,204 +30,161 @@ class pal_string m_value = TStdString(); } - pal_string(TStorageClass* str_ptr, const bool free) : - m_ptr(free ? str_ptr : nullptr), - m_value(str_ptr == nullptr ? TStdString() : str_ptr) - { - if (str_ptr == nullptr && !free) - { + pal_string(TStorageClass *str_ptr, const bool free) : m_ptr(free ? str_ptr : nullptr), + m_value(str_ptr == nullptr ? TStdString() : str_ptr) { + if (str_ptr == nullptr && !free) { throw std::runtime_error("str_ptr cannot be nullptr when free is false"); } } // Copy - pal_string(const pal_string&) noexcept = delete; - pal_string& operator=(const pal_string&) noexcept = delete; + pal_string(const pal_string &) noexcept = delete; + + pal_string &operator=(const pal_string &) noexcept = delete; // Move - pal_string(pal_string&&) noexcept = delete; - pal_string& operator=(pal_string&&) noexcept = delete; + pal_string(pal_string &&) noexcept = delete; - friend std::basic_ostream& operator<<(std::basic_ostream& out, const pal_string& pal_string) - { + pal_string &operator=(pal_string &&) noexcept = delete; + + friend std::basic_ostream &operator<<(std::basic_ostream &out, + const pal_string &pal_string) { out << pal_string.m_value; return out; } - virtual TStorageClass* dup() = 0; + virtual TStorageClass *dup() = 0; - TStorageClass* data() - { + TStorageClass *data() { return m_value.data(); } - void prepend_if(const bool yes, const TStdString& string) - { - if(!yes) - { + void prepend_if(const bool yes, const TStdString &string) { + if (!yes) { return; } prepend(string); } - void prepend(const TStdString& string) - { - m_value = m_value.insert(0, string); + void prepend(const TStdString &string) { + m_value = m_value.insert(0, string); } - void append_if(const bool yes, const TStdString& string) - { - if(!yes) - { + void append_if(const bool yes, const TStdString &string) { + if (!yes) { return; } append(string); } - void append(const TStdString& string) - { + void append(const TStdString &string) { m_value = m_value.append(string); } - void append_if_not_ends_width(const TStdString& string) - { + void append_if_not_ends_width(const TStdString &string) { append_if(!ends_with(string), string); } - void remove_if_ends_width(const TStdString& string) - { - if(!ends_with(string)) - { + void remove_if_ends_width(const TStdString &string) { + if (!ends_with(string)) { return; } const auto pos = m_value.find_last_of(string); - if(pos == std::string::npos) - { + if (pos == std::string::npos) { return; } m_value = m_value.substr(0, pos); } - TStdString str() - { + TStdString str() { return m_value; } - bool ends_with(const TStdString& string) - { - return m_value.size() >= string.size() - && 0 == m_value.compare(m_value.size() - string.size(), string.size(), string); + bool ends_with(const TStdString &string) { + return m_value.size() >= string.size() + && 0 == m_value.compare(m_value.size() - string.size(), string.size(), string); } - bool starts_with(const TStdString& string) - { - return m_value.size() >= string.size() - && 0 == m_value.compare(0, string.size(), string); + bool starts_with(const TStdString &string) { + return m_value.size() >= string.size() + && 0 == m_value.compare(0, string.size(), string); } - bool empty() - { + bool empty() { return m_value.empty(); } - bool empty_or_whitespace() - { + bool empty_or_whitespace() { return empty() || m_value.find_first_not_of(' ') == m_value.npos; } - size_t size() - { + size_t size() { return m_value.size(); } - [[nodiscard]] const TStorageClass* c_str() const noexcept - { + [[nodiscard]] const TStorageClass *c_str() const noexcept { return m_value.c_str(); } - }; -class pal_utf8_string final : public pal_string -{ - pal_utf8_string(char* utf8_string, const bool free) : pal_string>(utf8_string, free) - { +class pal_utf8_string final : public pal_string { + pal_utf8_string(char *utf8_string, const bool free) : pal_string >( + utf8_string, free) { } public: - pal_utf8_string() : pal_utf8_string(nullptr, false) - { - + pal_utf8_string() : pal_utf8_string(nullptr, false) { } - explicit pal_utf8_string(const size_t size) : pal_utf8_string(new char[size], true) - { - + explicit pal_utf8_string(const size_t size) : pal_utf8_string(new char[size], true) { } - explicit pal_utf8_string(wchar_t* utf16_string) : pal_utf8_string(pal_str_narrow(utf16_string), true) - { - + explicit pal_utf8_string(wchar_t *utf16_string) : pal_utf8_string(pal_str_narrow(utf16_string), true) { } - explicit pal_utf8_string(const std::wstring& utf16_string) : pal_utf8_string(pal_str_narrow(utf16_string.data()), true) - { - + explicit pal_utf8_string(const std::wstring &utf16_string) : pal_utf8_string( + pal_str_narrow(utf16_string.data()), true) { } - char* dup() override - { + char *dup() override { return _strdup(m_value.c_str()); } - - void to_backward_slashes() - { + + void to_backward_slashes() { std::replace(m_value.begin(), m_value.end(), '/', '\\'); } - }; -class pal_utf16_string final : public pal_string -{ - pal_utf16_string(wchar_t* utf16_string, const bool free) : pal_string>(utf16_string, free) - { +class pal_utf16_string final : public pal_string { + pal_utf16_string(wchar_t *utf16_string, const bool free) : pal_string >( + utf16_string, free) { } public: - pal_utf16_string() : pal_utf16_string(nullptr, false) - { - + pal_utf16_string() : pal_utf16_string(nullptr, false) { } - explicit pal_utf16_string(const size_t size) : pal_utf16_string(new wchar_t[size], true) - { - + explicit pal_utf16_string(const size_t size) : pal_utf16_string(new wchar_t[size], true) { } - explicit pal_utf16_string(const std::wstring& utf16_string) : pal_utf16_string(_wcsdup(utf16_string.data()), true) - { - + explicit pal_utf16_string(const std::wstring &utf16_string) : pal_utf16_string(_wcsdup(utf16_string.data()), true) { } - explicit pal_utf16_string(char* utf8_string) : pal_utf16_string(pal_str_widen(utf8_string), true) - { - + explicit pal_utf16_string(char *utf8_string) : pal_utf16_string(pal_str_widen(utf8_string), true) { } - explicit pal_utf16_string(const std::string& utf8_string) : pal_utf16_string(pal_str_widen(utf8_string.data()), true) - { - + explicit pal_utf16_string(const std::string &utf8_string) : pal_utf16_string( + pal_str_widen(utf8_string.data()), true) { } - wchar_t* dup() override - { + wchar_t *dup() override { return _wcsdup(m_value.c_str()); } - - void to_backward_slashes() - { + + void to_backward_slashes() { std::replace(m_value.begin(), m_value.end(), '/', '\\'); } }; -#endif +#endif \ No newline at end of file diff --git a/src/Snap.CoreRun.Pal/src/pal.cpp b/src/Snap.CoreRun.Pal/src/pal.cpp index c2d997af..13b8914f 100644 --- a/src/Snap.CoreRun.Pal/src/pal.cpp +++ b/src/Snap.CoreRun.Pal/src/pal.cpp @@ -19,7 +19,7 @@ #include // dlopen #include // kill #include // nanosleep -static const char* symlink_entrypoint_executable = "/proc/self/exe"; +static const char *symlink_entrypoint_executable = "/proc/self/exe"; #elif defined(PAL_PLATFORM_MACOS) #include // wait #include // getcwd @@ -36,8 +36,7 @@ static const char* symlink_entrypoint_executable = nullptr; // macOS uses differ #include // - Generic -PAL_API BOOL PAL_CALLING_CONVENTION pal_isdebuggerpresent() -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_isdebuggerpresent() { #if defined(PAL_PLATFORM_WINDOWS) return IsDebuggerPresent() ? TRUE : FALSE; #elif defined(PAL_PLATFORM_LINUX) @@ -46,22 +45,19 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_isdebuggerpresent() char buf[2048]; int status_fd = open("/proc/self/status", O_RDONLY); - if (status_fd == -1) - { + if (status_fd == -1) { return FALSE; } auto num_read = read(status_fd, buf, sizeof(buf) - 1); - if (num_read > 0) - { + if (num_read > 0) { static const char TracerPid[] = "TracerPid:"; char *tracer_pid; buf[num_read] = '\0'; tracer_pid = strstr(buf, TracerPid); - if (tracer_pid) - { + if (tracer_pid) { debugger_present = std::stoi(tracer_pid + sizeof(TracerPid) - 1) != 0; } } @@ -74,17 +70,15 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_isdebuggerpresent() #endif } -PAL_API BOOL pal_mitigate_dll_hijacking() -{ -#if defined(PAL_PLATFORM_WINDOWS) +PAL_API BOOL pal_mitigate_dll_hijacking() { +#if defined(PAL_PLATFORM_WINDOWS) LOGV << "Dll mitigation enabled"; // https://github.com/Squirrel/Squirrel.Windows/pull/1444 // Some libraries are still loaded from the current directories. // If we pre-load them with an absolute path then we are good. - const auto preload_libs = []() - { + const auto preload_libs = []() { wchar_t sys32_folder[MAX_PATH]; GetSystemDirectory(sys32_folder, MAX_PATH); @@ -100,29 +94,26 @@ PAL_API BOOL pal_mitigate_dll_hijacking() LoadLibrary(logoncli.c_str()); LoadLibrary(sspicli.c_str()); - if (pal_is_windows_8_or_greater()) - { + if (pal_is_windows_8_or_greater()) { const auto path_cch = std::wstring(sys32_folder) + L"\\api-ms-win-core-path-l1-1-0.dll"; LoadLibrary(path_cch.c_str()); } }; - const auto mitigate_dll_hijacking = [preload_libs]() - { + const auto mitigate_dll_hijacking = [preload_libs]() { // Set the default DLL lookup directory to System32 for ourselves and kernel32.dll // NB! This means that any subsequent LoadLibrary calls will only be able to load // DLLS from the SYSTEM32 directory. SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32); - auto* const h_kernel32 = LoadLibrary(L"kernel32.dll"); + auto *const h_kernel32 = LoadLibrary(L"kernel32.dll"); assert(h_kernel32 != NULL); - using SetDefaultDllDirectoriesFN = BOOL(WINAPI*)(DWORD DirectoryFlags); + using SetDefaultDllDirectoriesFN = BOOL(WINAPI *)(DWORD DirectoryFlags); const auto set_default_dll_directories_fn = reinterpret_cast( GetProcAddress(h_kernel32, "SetDefaultDllDirectories")); - if (set_default_dll_directories_fn) - { + if (set_default_dll_directories_fn) { (*set_default_dll_directories_fn)(LOAD_LIBRARY_SEARCH_SYSTEM32); } @@ -138,53 +129,46 @@ PAL_API BOOL pal_mitigate_dll_hijacking() } -PAL_API BOOL PAL_CALLING_CONVENTION pal_wait_for_debugger() -{ - while (!pal_isdebuggerpresent()) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_wait_for_debugger() { + while (!pal_isdebuggerpresent()) { pal_sleep_ms(100); } return TRUE; } -PAL_API BOOL PAL_CALLING_CONVENTION pal_load_library(const char * name_in, BOOL pinning_required, void** instance_out) -{ - if (name_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_load_library(const char *name_in, BOOL pinning_required, void **instance_out) { + if (name_in == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) pal_utf16_string name_in_utf16_string(name_in); - auto* const h_module = LoadLibraryEx(name_in_utf16_string.data(), nullptr, 0); - if (!h_module) - { + auto *const h_module = LoadLibraryEx(name_in_utf16_string.data(), nullptr, 0); + if (!h_module) { LOGE << "Failed load dll: " << name_in_utf16_string << ". Error code: " << GetLastError(); return FALSE; } - if (pinning_required) - { + if (pinning_required) { HMODULE dummy_module; - if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN, name_in_utf16_string.data(), &dummy_module)) - { + if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN, name_in_utf16_string.data(), &dummy_module)) { LOGE << "Failed to pin dll: " << name_in_utf16_string << ". Error code: " << GetLastError(); pal_free_library(h_module); return FALSE; } } - *instance_out = static_cast(h_module); + *instance_out = static_cast(h_module); return TRUE; #elif defined(PAL_PLATFORM_LINUX) PAL_UNUSED(pinning_required); auto instance = dlopen(name_in, RTLD_NOW | RTLD_LOCAL); - if (!instance) - { - LOGE << "Failed to load dynamic library: " << name_in << ". Errno: " << errno << ". Error code: " << std::strerror(errno); + if (!instance) { + LOGE << "Failed to load dynamic library: " << name_in << ". Errno: " << errno << ". Error code: " << + std::strerror(errno); return FALSE; } @@ -195,16 +179,13 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_load_library(const char * name_in, BOOL #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_free_library(void* instance_in) -{ - if (instance_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_free_library(void *instance_in) { + if (instance_in == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) const auto free_library_result = FreeLibrary(static_cast(instance_in)); - if (free_library_result == 0) - { + if (free_library_result == 0) { return TRUE; } return FALSE; @@ -215,27 +196,23 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_free_library(void* instance_in) #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_getprocaddress(void* instance_in, const char* name_in, void** ptr_out) -{ - if (instance_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_getprocaddress(void *instance_in, const char *name_in, void **ptr_out) { + if (instance_in == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) - auto* const h_module = static_cast(instance_in); + auto *const h_module = static_cast(instance_in); const auto h_module_ptr_out = GetProcAddress(h_module, name_in); - if (h_module_ptr_out == nullptr) - { + if (h_module_ptr_out == nullptr) { return FALSE; } - *ptr_out = reinterpret_cast(h_module_ptr_out); + *ptr_out = reinterpret_cast(h_module_ptr_out); return TRUE; #elif defined(PAL_PLATFORM_LINUX) auto dlsym_ptr_out = dlsym(instance_in, name_in); - if (dlerror() != nullptr) - { + if (dlerror() != nullptr) { return FALSE; } *ptr_out = dlsym_ptr_out; @@ -258,10 +235,8 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_is_elevated() { DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &administrators_group); - if (is_elevated) - { - if (!CheckTokenMembership(nullptr, administrators_group, &is_elevated)) - { + if (is_elevated) { + if (!CheckTokenMembership(nullptr, administrators_group, &is_elevated)) { is_elevated = FALSE; } FreeSid(administrators_group); @@ -277,11 +252,9 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_is_elevated() { #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_set_icon(const char * filename_in, const char * icon_filename_in) -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_set_icon(const char *filename_in, const char *icon_filename_in) { if (!pal_fs_file_exists(filename_in) - || !pal_fs_file_exists(icon_filename_in)) - { + || !pal_fs_file_exists(icon_filename_in)) { return FALSE; } @@ -289,16 +262,13 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_set_icon(const char * filename_in, const pal_utf16_string filename_in_utf16_string(filename_in); pal_utf16_string icon_filename_in_utf16_string(icon_filename_in); snap::rcedit::ResourceUpdater resource_updater; - if (!resource_updater.Load(filename_in_utf16_string.data())) - { + if (!resource_updater.Load(filename_in_utf16_string.data())) { return FALSE; } - if (!resource_updater.SetIcon(icon_filename_in_utf16_string.data())) - { + if (!resource_updater.SetIcon(icon_filename_in_utf16_string.data())) { return FALSE; } - if (!resource_updater.Commit()) - { + if (!resource_updater.Commit()) { return FALSE; } return TRUE; @@ -307,18 +277,15 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_set_icon(const char * filename_in, const #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_has_icon(const char * filename_in) -{ - if (!pal_fs_file_exists(filename_in)) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_has_icon(const char *filename_in) { + if (!pal_fs_file_exists(filename_in)) { return FALSE; } -#if defined(PAL_PLATFORM_WINDOWS) +#if defined(PAL_PLATFORM_WINDOWS) pal_utf16_string filename_in_utf16_string(filename_in); snap::rcedit::ResourceUpdater resourceUpdater; - if (!resourceUpdater.Load(filename_in_utf16_string.data())) - { + if (!resourceUpdater.Load(filename_in_utf16_string.data())) { return FALSE; } return resourceUpdater.HasIcon() ? TRUE : FALSE; @@ -327,17 +294,14 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_has_icon(const char * filename_in) #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_cwd(char **cwd_out) -{ - const auto real_path = std::make_unique(nullptr); - if (!pal_process_get_real_path(real_path.get())) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_cwd(char **cwd_out) { + const auto real_path = std::make_unique(nullptr); + if (!pal_process_get_real_path(real_path.get())) { return FALSE; } - const auto real_path_cwd = std::make_unique(nullptr); - if (!pal_path_get_directory_name_from_file_path(*real_path, real_path_cwd.get())) - { + const auto real_path_cwd = std::make_unique(nullptr); + if (!pal_path_get_directory_name_from_file_path(*real_path, real_path_cwd.get())) { return FALSE; } @@ -346,20 +310,17 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_cwd(char **cwd_out) return TRUE; } -PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_real_path(char **real_path_out) -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_real_path(char **real_path_out) { #if defined(PAL_PLATFORM_WINDOWS) wchar_t buffer[PAL_MAX_PATH]; - if (0 == GetModuleFileName(nullptr, buffer, PAL_MAX_PATH)) - { + if (0 == GetModuleFileName(nullptr, buffer, PAL_MAX_PATH)) { return FALSE; } *real_path_out = pal_utf8_string(buffer).dup(); return TRUE; #elif defined(PAL_PLATFORM_LINUX) char real_path[PAL_MAX_PATH]; - if (realpath(symlink_entrypoint_executable, real_path) != nullptr && real_path[0] != '\0') - { + if (realpath(symlink_entrypoint_executable, real_path) != nullptr && real_path[0] != '\0') { std::string real_path_str(real_path); *real_path_out = strdup(real_path_str.c_str()); return TRUE; @@ -370,22 +331,18 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_real_path(char **real_path_o #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_process_is_running(pal_pid_t pid) -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_process_is_running(pal_pid_t pid) { #if defined(PAL_PLATFORM_WINDOWS) - auto* const pss = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + auto *const pss = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); bool is_running = false; - if (pss != INVALID_HANDLE_VALUE) - { + if (pss != INVALID_HANDLE_VALUE) { PROCESSENTRY32 pe = {}; pe.dwSize = sizeof (PROCESSENTRY32); - if (Process32First(pss, &pe)) - { + if (Process32First(pss, &pe)) { is_running = pe.th32ProcessID == pid; - while (!is_running && Process32Next(pss, &pe)) - { + while (!is_running && Process32Next(pss, &pe)) { is_running = pe.th32ProcessID == pid; } } @@ -394,10 +351,9 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_is_running(pal_pid_t pid) return is_running ? TRUE : FALSE; #elif defined(PAL_PLATFORM_LINUX) - struct stat dontcare = { 0 }; + struct stat dontcare = {0}; std::string proc_path("/proc/" + std::to_string(pid)); - if (stat(proc_path.c_str(), &dontcare) != -1) - { + if (stat(proc_path.c_str(), &dontcare) != -1) { return TRUE; } return FALSE; @@ -406,13 +362,11 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_is_running(pal_pid_t pid) #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_process_kill(pal_pid_t pid) -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_process_kill(pal_pid_t pid) { #if defined(PAL_PLATFORM_WINDOWS) - auto* const process = OpenProcess(SYNCHRONIZE, FALSE, pid); + auto *const process = OpenProcess(SYNCHRONIZE, FALSE, pid); auto process_killed = FALSE; - if (process != nullptr) - { + if (process != nullptr) { process_killed = TerminateProcess(process, 1); assert(0 != CloseHandle(process)); } @@ -425,8 +379,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_kill(pal_pid_t pid) #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_pid(pal_pid_t* pid_out) -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_pid(pal_pid_t *pid_out) { BOOL has_pid; #if defined(PAL_PLATFORM_WINDOWS) has_pid = TRUE; @@ -439,19 +392,16 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_pid(pal_pid_t* pid_out) } -PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_name(char **exe_name_out) -{ - const auto real_path = std::make_unique(nullptr); - if (!pal_process_get_real_path(real_path.get())) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_name(char **exe_name_out) { + const auto real_path = std::make_unique(nullptr); + if (!pal_process_get_real_path(real_path.get())) { return FALSE; } const std::string real_path_str(*real_path); const auto directory_separator_pos = real_path_str.find_last_of(PAL_DIRECTORY_SEPARATOR_C); - if (std::string::npos == directory_separator_pos) - { + if (std::string::npos == directory_separator_pos) { return FALSE; } @@ -462,26 +412,23 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_get_name(char **exe_name_out) } PAL_API BOOL PAL_CALLING_CONVENTION pal_process_exec(const char *filename_in, const char *working_dir_in, - const int argc_in, char **argv_in, pal_exit_code_t *exit_code_out) -{ - if (filename_in == nullptr) - { + const int argc_in, char **argv_in, + pal_exit_code_t *exit_code_out) { + if (filename_in == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) - if (working_dir_in == nullptr) - { + if (working_dir_in == nullptr) { return FALSE; } const auto filename_in_str = std::string(filename_in); - if (filename_in_str.size() > PAL_MAX_PATH) - { + if (filename_in_str.size() > PAL_MAX_PATH) { // pCommandLine is limited to MAX_PATH characters. LOGE << "Unable to start executable: " << filename_in_str << ". " - << "The path component (filename) exceeds " << PAL_MAX_PATH << " characters. " - << "This is a hard limit in the WIN32 API and there is nothing that can be done about it."; + << "The path component (filename) exceeds " << PAL_MAX_PATH << " characters. " + << "This is a hard limit in the WIN32 API and there is nothing that can be done about it."; return FALSE; } @@ -489,13 +436,10 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_exec(const char *filename_in, co cmd_line += filename_in_str; cmd_line += "\" "; - if (argv_in != nullptr && argc_in > 0) - { - for (auto i = 0; i < argc_in; i++) - { + if (argv_in != nullptr && argc_in > 0) { + for (auto i = 0; i < argc_in; i++) { cmd_line += argv_in[i]; - if (i + 1 < argc_in) - { + if (i + 1 < argc_in) { cmd_line += " "; } } @@ -509,27 +453,26 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_exec(const char *filename_in, co pi.hProcess = nullptr; const auto create_process_result = CreateProcess(nullptr, - lp_command_line_utf16_string.data(), - nullptr, nullptr, false, - 0, nullptr, lp_current_directory_utf16_string.data(), &si, &pi); + lp_command_line_utf16_string.data(), + nullptr, nullptr, false, + 0, nullptr, lp_current_directory_utf16_string.data(), &si, &pi); - if (!create_process_result) - { + if (!create_process_result) { LOGE << "CreateProcess: " << cmd_line << ". Error code: " << GetLastError(); return FALSE; } const auto result = WaitForSingleObject(pi.hProcess, INFINITE); - if (result != WAIT_OBJECT_0) - { - LOGE << "WaitForSingleObject: Process exit prematurely. Result: " << result << ". Error code: " << GetLastError(); + if (result != WAIT_OBJECT_0) { + LOGE << "WaitForSingleObject: Process exit prematurely. Result: " << result << ". Error code: " << + GetLastError(); return FALSE; } DWORD exit_code; - if (FALSE == GetExitCodeProcess(pi.hProcess, &exit_code)) - { - LOGE << "GetExitCodeProcess: Process exit prematurely. Result: " << result << ". Error code: " << GetLastError(); + if (FALSE == GetExitCodeProcess(pi.hProcess, &exit_code)) { + LOGE << "GetExitCodeProcess: Process exit prematurely. Result: " << result << ". Error code: " << + GetLastError(); return FALSE; } @@ -541,18 +484,17 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_exec(const char *filename_in, co #elif defined(PAL_PLATFORM_LINUX) if (working_dir_in != nullptr - && 0 != chdir(working_dir_in)) - { - LOGE << "Error changing working directory: " << working_dir_in << ". Errno: " << errno << ". Error code: " << std::strerror(errno); + && 0 != chdir(working_dir_in)) { + LOGE << "Error changing working directory: " << working_dir_in << ". Errno: " << errno << ". Error code: " << + std::strerror(errno); return FALSE; } auto exec_args_len = std::max(1, argc_in + 1); - auto exec_args_tmp = new char*[exec_args_len]; + auto exec_args_tmp = new char *[exec_args_len]; exec_args_tmp[0] = _strdup(filename_in); - for (auto i = 0; i < argc_in; i++) - { + for (auto i = 0; i < argc_in; i++) { exec_args_tmp[i + 1] = argv_in[i]; } @@ -560,18 +502,17 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_exec(const char *filename_in, co auto exit_status = 0; auto child_pid = fork(); - if (child_pid == 0) - { - if (execvp(exec_args_tmp[0], exec_args_tmp) == -1) - { - LOGE << "exec failed: " << exec_args_tmp[0] << ". Errno: " << errno << ". Error code: " << std::strerror(errno); + if (child_pid == 0) { + if (execvp(exec_args_tmp[0], exec_args_tmp) == -1) { + LOGE << "exec failed: " << exec_args_tmp[0] << ". Errno: " << errno << ". Error code: " << + std::strerror(errno); return FALSE; } - } - else if (child_pid > 0) { + } else if (child_pid > 0) { wait(&exit_status); *exit_code_out = WEXITSTATUS(exit_status); - LOGV << "Process exited. Filename: " << exec_args_tmp[0] << ". Pid: " << child_pid << ". Exit code: " << *exit_code_out; + LOGV << "Process exited. Filename: " << exec_args_tmp[0] << ". Pid: " << child_pid << ". Exit code: " << * + exit_code_out; return *exit_code_out == -1 ? FALSE : TRUE; } return FALSE; @@ -581,24 +522,21 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_exec(const char *filename_in, co } PAL_API BOOL PAL_CALLING_CONVENTION pal_process_daemonize(const char *filename_in, const char *working_dir_in, - const int argc_in, char **argv_in, - const int cmd_show_in /* Only applicable on Windows */, - pal_pid_t *pid_out) -{ + const int argc_in, char **argv_in, + const int cmd_show_in /* Only applicable on Windows */, + pal_pid_t *pid_out) { if (filename_in == nullptr - || working_dir_in == nullptr) - { + || working_dir_in == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) const auto filename_in_str = std::string(filename_in); - if (filename_in_str.size() > PAL_MAX_PATH) - { + if (filename_in_str.size() > PAL_MAX_PATH) { // pCommandLine is limited to MAX_PATH characters. LOGE << "Unable to start executable: " << filename_in_str << ". " - << "The path component (filename) exceeds " << PAL_MAX_PATH << " characters. " - << "This is a hard limit in the WIN32 API and there is nothing that can be done about it."; + << "The path component (filename) exceeds " << PAL_MAX_PATH << " characters. " + << "This is a hard limit in the WIN32 API and there is nothing that can be done about it."; return FALSE; } @@ -606,11 +544,9 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_daemonize(const char *filename_i cmd_line += filename_in_str; cmd_line += "\" "; - for (auto i = 0; i < argc_in; i++) - { + for (auto i = 0; i < argc_in; i++) { cmd_line += argv_in[i]; - if (i + 1 < argc_in) - { + if (i + 1 < argc_in) { cmd_line += " "; } } @@ -627,11 +563,10 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_daemonize(const char *filename_i pi.hProcess = nullptr; const auto create_process_result = CreateProcess(nullptr, lp_command_line_utf16_string.data(), - nullptr, nullptr, false, - 0, nullptr, lp_current_directory_utf16_string.data(), &si, &pi); + nullptr, nullptr, false, + 0, nullptr, lp_current_directory_utf16_string.data(), &si, &pi); - if (!create_process_result) - { + if (!create_process_result) { LOGE << "CreateProcess: " << cmd_line << ". Error code: " << GetLastError(); return FALSE; } @@ -646,33 +581,30 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_daemonize(const char *filename_i PAL_UNUSED(cmd_show_in); if (working_dir_in != nullptr - && 0 != chdir(working_dir_in)) - { - LOGE << "Error changing working directory: " << working_dir_in << ". Errno: " << errno << ". Error code: " << std::strerror(errno); + && 0 != chdir(working_dir_in)) { + LOGE << "Error changing working directory: " << working_dir_in << ". Errno: " << errno << ". Error code: " << + std::strerror(errno); return FALSE; } auto exec_argc = std::max(1, argc_in + 1); - auto exec_args_tmp = new char*[exec_argc]; + auto exec_args_tmp = new char *[exec_argc]; exec_args_tmp[0] = _strdup(filename_in); - for (auto i = 0; i < argc_in; i++) - { + for (auto i = 0; i < argc_in; i++) { exec_args_tmp[i + 1] = argv_in[i]; } exec_args_tmp[exec_argc] = nullptr; auto child_pid = fork(); - if (child_pid == 0) - { - if (execvp(exec_args_tmp[0], exec_args_tmp) == -1) - { - LOGE << "exec failed: " << exec_args_tmp[0] << ". Errno: " << errno << ". Error code: " << std::strerror(errno); + if (child_pid == 0) { + if (execvp(exec_args_tmp[0], exec_args_tmp) == -1) { + LOGE << "exec failed: " << exec_args_tmp[0] << ". Errno: " << errno << ". Error code: " << + std::strerror(errno); return FALSE; } - } - else if (child_pid > 0) { + } else if (child_pid > 0) { *pid_out = child_pid; } @@ -682,13 +614,12 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_process_daemonize(const char *filename_i #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_sleep_ms(const uint32_t milliseconds) -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_sleep_ms(const uint32_t milliseconds) { #if defined(PAL_PLATFORM_WINDOWS) Sleep(milliseconds); return TRUE; #elif defined(PAL_PLATFORM_LINUX) || defined(PAL_PLATFORM_MACOS) - struct timespec ts = { 0 }; + struct timespec ts = {0}; ts.tv_sec = milliseconds / 1000; ts.tv_nsec = (milliseconds % 1000) * 1000000; nanosleep(&ts, nullptr); @@ -698,8 +629,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_sleep_ms(const uint32_t milliseconds) #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows() -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows() { #if defined(PAL_PLATFORM_WINDOWS) return TRUE; #else @@ -707,8 +637,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows() #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows_8_or_greater() -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows_8_or_greater() { #if defined(PAL_PLATFORM_WINDOWS) return ::IsWindows8OrGreater() ? TRUE : FALSE; #else @@ -716,8 +645,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows_8_or_greater() #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows_7_or_greater() -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows_7_or_greater() { #if defined(PAL_PLATFORM_WINDOWS) return ::IsWindows7OrGreater() ? TRUE : FALSE; #else @@ -725,8 +653,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_is_windows_7_or_greater() #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_is_linux() -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_is_linux() { #if defined(PAL_PLATFORM_LINUX) return TRUE; #else @@ -734,8 +661,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_is_linux() #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_is_macos() -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_is_macos() { #if defined(PAL_PLATFORM_MACOS) return TRUE; #else @@ -743,24 +669,24 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_is_macos() #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_is_unknown_os() -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_is_unknown_os() { return pal_is_linux() - || pal_is_windows() - || pal_is_macos() ? FALSE : TRUE; + || pal_is_windows() + || pal_is_macos() + ? FALSE + : TRUE; } // - Environment -PAL_API BOOL PAL_CALLING_CONVENTION pal_env_set(const char* name_in, const char* value_in) -{ - if (name_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_env_set(const char *name_in, const char *value_in) { + if (name_in == nullptr) { return FALSE; } -#if defined(PAL_PLATFORM_WINDOWS) +#if defined(PAL_PLATFORM_WINDOWS) pal_utf16_string name_in_utf16_string(name_in); pal_utf16_string value_in_utf16_string(value_in == nullptr ? "" : value_in); - const auto success = SetEnvironmentVariable(name_in_utf16_string.data(), value_in_utf16_string.empty() ? nullptr : value_in_utf16_string.data()); + const auto success = SetEnvironmentVariable(name_in_utf16_string.data(), + value_in_utf16_string.empty() ? nullptr : value_in_utf16_string.data()); return success != 0 ? TRUE : FALSE; #elif defined(PAL_PLATFORM_LINUX) const auto success = value_in == nullptr ? unsetenv(name_in) : setenv(name_in, value_in, 1 /* overwrite */); @@ -770,20 +696,18 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_env_set(const char* name_in, const char* #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_env_get(const char * environment_variable_in, char ** environment_variable_value_out) -{ - if (environment_variable_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_env_get(const char *environment_variable_in, + char **environment_variable_value_out) { + if (environment_variable_in == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) pal_utf16_string environment_variable_in_utf16_string(environment_variable_in); const auto buffer_size = 65535; - auto* const buffer = new wchar_t[buffer_size]; + auto *const buffer = new wchar_t[buffer_size]; const auto actual_len = GetEnvironmentVariable(environment_variable_in_utf16_string.data(), buffer, buffer_size); - if (actual_len <= 0) - { + if (actual_len <= 0) { delete[] buffer; return FALSE; } @@ -795,8 +719,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_env_get(const char * environment_variabl return TRUE; #elif defined(PAL_PLATFORM_LINUX) const auto value = ::getenv(environment_variable_in); - if (value == nullptr) - { + if (value == nullptr) { return FALSE; } *environment_variable_value_out = strdup(value); @@ -806,18 +729,15 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_env_get(const char * environment_variabl #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_env_get_bool(const char * environment_variable_in) -{ - char* environment_variable_value_out = nullptr; - if (!pal_env_get(environment_variable_in, &environment_variable_value_out)) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_env_get_bool(const char *environment_variable_in) { + char *environment_variable_value_out = nullptr; + if (!pal_env_get(environment_variable_in, &environment_variable_value_out)) { return FALSE; } auto true_or_false = FALSE; if (pal_str_iequals(environment_variable_value_out, "1") - || pal_str_iequals(environment_variable_value_out, "true")) - { + || pal_str_iequals(environment_variable_value_out, "true")) { true_or_false = TRUE; } @@ -826,10 +746,8 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_env_get_bool(const char * environment_va return true_or_false; } -PAL_API BOOL PAL_CALLING_CONVENTION pal_env_expand_str(const char * environment_in, char ** environment_out) -{ - if (environment_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_env_expand_str(const char *environment_in, char **environment_out) { + if (environment_in == nullptr) { return FALSE; } @@ -845,9 +763,8 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_env_expand_str(const char * environment_ std::smatch match; while (std::regex_search(environment_in_str, match, expression)) { const auto match_str = match[1].str(); - char* environment_variable_value = nullptr; - if (!pal_env_get(match_str.c_str(), &environment_variable_value)) - { + char *environment_variable_value = nullptr; + if (!pal_env_get(match_str.c_str(), &environment_variable_value)) { continue; } @@ -859,8 +776,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_env_expand_str(const char * environment_ replacements++; } - if (replacements <= 0) - { + if (replacements <= 0) { return FALSE; } @@ -886,10 +802,8 @@ BOOL pal_fs_chmod(const char *path_in, const pal_mode_t mode) { return is_success; } -PAL_API BOOL PAL_CALLING_CONVENTION pal_path_get_directory_name_from_file_path(const char * path_in, char ** path_out) -{ - if (path_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_path_get_directory_name_from_file_path(const char *path_in, char **path_out) { + if (path_in == nullptr) { return FALSE; } @@ -899,25 +813,21 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_get_directory_name_from_file_path(c wchar_t path_in_without_filespec[PAL_MAX_PATH]; wcscpy_s(path_in_without_filespec, PAL_MAX_PATH, path_in_utf16_string.data()); - if (pal_is_windows_8_or_greater()) - { + if (pal_is_windows_8_or_greater()) { pal_module pathcch_module("api-ms-win-core-path-l1-1-0.dll"); - if (!pathcch_module.is_loaded()) - { + if (!pathcch_module.is_loaded()) { return FALSE; } - using PathCchRemoveFileSpecFn = HRESULT(WINAPI*)(PWSTR pszPath, size_t cchPath); + using PathCchRemoveFileSpecFn = HRESULT(WINAPI *)(PWSTR pszPath, size_t cchPath); const auto path_cch_remove_file_spec_fn = pathcch_module.bind("PathCchRemoveFileSpec"); - if (path_cch_remove_file_spec_fn == nullptr) - { + if (path_cch_remove_file_spec_fn == nullptr) { return FALSE; } const auto hr = path_cch_remove_file_spec_fn(path_in_without_filespec, PAL_MAX_PATH); - if (!SUCCEEDED(hr)) - { + if (!SUCCEEDED(hr)) { return FALSE; } @@ -933,8 +843,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_get_directory_name_from_file_path(c #elif defined(PAL_PLATFORM_LINUX) auto path_in_cpy = strdup(path_in); auto dir = dirname(path_in_cpy); - if (dir != nullptr) - { + if (dir != nullptr) { // Both dirname() and basename() return pointers to null-terminated // strings. (Do not pass these pointers to free(3).) *path_out = strdup(dir); @@ -947,18 +856,15 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_get_directory_name_from_file_path(c #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_path_get_directory_name(const char * path_in, char ** path_out) -{ - if (path_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_path_get_directory_name(const char *path_in, char **path_out) { + if (path_in == nullptr) { return FALSE; } const std::string path_in_s(path_in); const auto directory_name_start_pos = path_in_s.find_last_of(PAL_DIRECTORY_SEPARATOR_C); - if (directory_name_start_pos == std::string::npos) - { + if (directory_name_start_pos == std::string::npos) { return FALSE; } @@ -973,8 +879,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_get_directory_name(const char * pat // https://github.com/qpalzmqaz123/path_combine/blob/master/path_combine.c -inline int unix_path_combine_cleanup(char *path) -{ +inline int unix_path_combine_cleanup(char *path) { char *str; char *parent_dir; char *current_dir; @@ -1017,11 +922,9 @@ inline int unix_path_combine_cleanup(char *path) tail = path + strlen(path) - 1; if ('/' == *tail) { *tail = 0; - } - else if (0 == strcmp(tail - 1, "/.")) { + } else if (0 == strcmp(tail - 1, "/.")) { *(tail - 1) = 0; - } - else if (0 == strcmp(tail - 2, "/..")) { + } else if (0 == strcmp(tail - 2, "/..")) { strcat(path, "/"); unix_path_combine_cleanup(path); } @@ -1029,17 +932,14 @@ inline int unix_path_combine_cleanup(char *path) return 0; } -inline char* unix_path_combine(const char *path1, const char *path2, char *buffer) -{ +inline char *unix_path_combine(const char *path1, const char *path2, char *buffer) { if (pal_str_is_null_or_whitespace(path1) || pal_str_is_null_or_whitespace(path2)) { return nullptr; - } - else if (nullptr == path1) { + } else if (nullptr == path1) { strcpy(buffer, path2); goto EXIT; - } - else if (nullptr == path2) { + } else if (nullptr == path2) { strcpy(buffer, path1); goto EXIT; } @@ -1062,10 +962,8 @@ inline char* unix_path_combine(const char *path1, const char *path2, char *buffe } #endif -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_file_exists(const char * file_path_in) -{ - if (file_path_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_file_exists(const char *file_path_in) { + if (file_path_in == nullptr) { return FALSE; } @@ -1074,18 +972,15 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_file_exists(const char * file_path_in pal_utf16_string file_path_in_utf16_string(file_path_in); const auto file_attributes = GetFileAttributes(file_path_in_utf16_string.data()); if (file_attributes == INVALID_FILE_ATTRIBUTES - || file_attributes & FILE_ATTRIBUTE_DIRECTORY) - { + || file_attributes & FILE_ATTRIBUTE_DIRECTORY) { file_exists = FALSE; - } - else - { + } else { file_exists = PathFileExists(file_path_in_utf16_string.data()) == TRUE ? TRUE : FALSE; } return file_exists; #elif defined(PAL_PLATFORM_LINUX) - struct stat st = { 0 }; + struct stat st = {0}; file_exists = stat(file_path_in, &st) == 0 && (st.st_mode & S_IFDIR) == 0; return file_exists; #else @@ -1093,15 +988,15 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_file_exists(const char * file_path_in #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_impl(const char * path_in, const pal_fs_list_filter_callback_t filter_callback_in, - const char* filter_extension_in, char *** paths_out, size_t * paths_out_len, const int type) -{ - if (path_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_impl(const char *path_in, + const pal_fs_list_filter_callback_t filter_callback_in, + const char *filter_extension_in, char ***paths_out, + size_t *paths_out_len, const int type) { + if (path_in == nullptr) { return false; } - std::vector paths; + std::vector paths; #if defined(PAL_PLATFORM_WINDOWS) @@ -1113,56 +1008,47 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_impl(const char * path_in, const path_root_utf16_string.append(extension_filter_in_utf16_string.c_str()); WIN32_FIND_DATA file; - auto* const h_file = FindFirstFile(path_root_utf16_string.data(), &file); - if (h_file == INVALID_HANDLE_VALUE) - { + auto *const h_file = FindFirstFile(path_root_utf16_string.data(), &file); + if (h_file == INVALID_HANDLE_VALUE) { return FALSE; } - do - { - switch (type) - { - case 0: - if (!(file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - continue; - } - break; - case 1: - if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { + do { + switch (type) { + case 0: + if (!(file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + continue; + } + break; + case 1: + if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + continue; + } + break; + default: continue; - } - break; - default: - continue; } const auto relative_path = pal_utf8_string(file.cFileName).str(); if (relative_path == "." - || relative_path == "..") - { + || relative_path == "..") { continue; } - char* absolute_path = nullptr; - if (!pal_path_combine(path_in, relative_path.data(), &absolute_path)) - { + char *absolute_path = nullptr; + if (!pal_path_combine(path_in, relative_path.data(), &absolute_path)) { delete[] absolute_path; continue; } const auto filter_callback_fn = filter_callback_in; if (filter_callback_fn != nullptr - && !filter_callback_fn(absolute_path)) - { + && !filter_callback_fn(absolute_path)) { delete[] absolute_path; continue; } paths.emplace_back(absolute_path); - } while (FindNextFile(h_file, &file)); FindClose(h_file); @@ -1170,57 +1056,20 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_impl(const char * path_in, const #elif defined(PAL_PLATFORM_LINUX) std::string filter_extension_s(filter_extension_in == nullptr ? std::string() : filter_extension_in); - DIR* dir = opendir(path_in); - if (dir != nullptr) - { - struct dirent* entry; - while ((entry = readdir(dir)) != nullptr) - { + DIR *dir = opendir(path_in); + if (dir != nullptr) { + struct dirent *entry; + while ((entry = readdir(dir)) != nullptr) { std::string absolute_path_s; std::string entry_name(entry->d_name); - switch (type) - { - case 0: - if (entry->d_type != DT_DIR) - { - continue; - } - - if (entry_name == "." || entry_name == "..") - { - continue; - } - - absolute_path_s.assign(path_in); - absolute_path_s.append("/"); - absolute_path_s.append(entry_name); - - break; - case 1: - switch (entry->d_type) - { - default: - continue; - // Regular file - case DT_REG: - if (filter_extension_in != nullptr - && FALSE == pal_str_endswith(entry_name.c_str(), filter_extension_in)) - { + switch (type) { + case 0: + if (entry->d_type != DT_DIR) { continue; } - absolute_path_s.assign(path_in); - absolute_path_s.append("/"); - absolute_path_s.append(entry_name); - break; - - // Handle symlinks and file systems that do not support d_type - case DT_LNK: - case DT_UNKNOWN: - if (filter_extension_in != nullptr - && FALSE == pal_str_endswith(entry_name.c_str(), filter_extension_in)) - { + if (entry_name == "." || entry_name == "..") { continue; } @@ -1228,37 +1077,62 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_impl(const char * path_in, const absolute_path_s.append("/"); absolute_path_s.append(entry_name); - struct stat file_stat = { 0 }; - if (stat(absolute_path_s.c_str(), &file_stat) == -1) - { - absolute_path_s.clear(); - continue; - } - - // Must be a regular file. - if (!S_ISREG(file_stat.st_mode)) - { - absolute_path_s.clear(); - continue; + break; + case 1: + switch (entry->d_type) { + default: + continue; + // Regular file + case DT_REG: + if (filter_extension_in != nullptr + && FALSE == pal_str_endswith(entry_name.c_str(), filter_extension_in)) { + continue; + } + + absolute_path_s.assign(path_in); + absolute_path_s.append("/"); + absolute_path_s.append(entry_name); + break; + + // Handle symlinks and file systems that do not support d_type + case DT_LNK: + case DT_UNKNOWN: + if (filter_extension_in != nullptr + && FALSE == pal_str_endswith(entry_name.c_str(), filter_extension_in)) { + continue; + } + + absolute_path_s.assign(path_in); + absolute_path_s.append("/"); + absolute_path_s.append(entry_name); + + struct stat file_stat = {0}; + if (stat(absolute_path_s.c_str(), &file_stat) == -1) { + absolute_path_s.clear(); + continue; + } + + // Must be a regular file. + if (!S_ISREG(file_stat.st_mode)) { + absolute_path_s.clear(); + continue; + } + + break; } - break; - } - break; - default: - // void - break; + default: + // void + break; } - if (absolute_path_s.empty()) - { + if (absolute_path_s.empty()) { continue; } const auto filter_callback_fn = filter_callback_in; if (filter_callback_fn != nullptr - && !filter_callback_fn(absolute_path_s.c_str())) - { + && !filter_callback_fn(absolute_path_s.c_str())) { continue; } @@ -1271,10 +1145,9 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_impl(const char * path_in, const *paths_out_len = paths.size(); - auto* const paths_array = new char*[*paths_out_len]; + auto *const paths_array = new char *[*paths_out_len]; - for (auto i = 0u; i < *paths_out_len; i++) - { + for (auto i = 0u; i < *paths_out_len; i++) { paths_array[i] = paths[i]; } @@ -1283,24 +1156,24 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_impl(const char * path_in, const return TRUE; } -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_directories(const char * path_in, const pal_fs_list_filter_callback_t filter_callback_in, - const char* filter_extension_in, char *** directories_out, size_t* directories_out_len) -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_directories(const char *path_in, + const pal_fs_list_filter_callback_t filter_callback_in, + const char *filter_extension_in, char ***directories_out, + size_t *directories_out_len) { return pal_fs_list_impl(path_in, filter_callback_in, filter_extension_in, directories_out, directories_out_len, 0); } -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_files(const char * path_in, const pal_fs_list_filter_callback_t filter_callback_in, - const char* filter_extension_in, char *** files_out, size_t * files_out_len) -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_list_files(const char *path_in, + const pal_fs_list_filter_callback_t filter_callback_in, + const char *filter_extension_in, char ***files_out, + size_t *files_out_len) { return pal_fs_list_impl(path_in, filter_callback_in, filter_extension_in, files_out, files_out_len, 1); } -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_get_cwd(char ** working_directory_out) -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_get_cwd(char **working_directory_out) { #if defined(PAL_PLATFORM_WINDOWS) - wchar_t* buffer; - if ((buffer = _wgetcwd(nullptr, 0)) == nullptr) - { + wchar_t *buffer; + if ((buffer = _wgetcwd(nullptr, 0)) == nullptr) { return FALSE; } @@ -1310,8 +1183,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_get_cwd(char ** working_directory_out #elif defined(PAL_PLATFORM_LINUX) char cwd[PAL_MAX_PATH]; auto status = getcwd(cwd, sizeof(cwd)); - if (status != nullptr) - { + if (status != nullptr) { *working_directory_out = strdup(cwd); return TRUE; } @@ -1321,29 +1193,24 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_get_cwd(char ** working_directory_out #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_directory_exists(const char * path_in) -{ - if (path_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_directory_exists(const char *path_in) { + if (path_in == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) pal_utf16_string path_in_utf16_string(path_in); const auto attributes = GetFileAttributes(path_in_utf16_string.data()); - if (attributes == INVALID_FILE_ATTRIBUTES) - { + if (attributes == INVALID_FILE_ATTRIBUTES) { return FALSE; } - if (!(attributes & FILE_ATTRIBUTE_DIRECTORY)) - { + if (!(attributes & FILE_ATTRIBUTE_DIRECTORY)) { return FALSE; } return TRUE; #elif defined(PAL_PLATFORM_LINUX) auto directory = opendir(path_in); - if (directory != nullptr) - { + if (directory != nullptr) { assert(0 == closedir(directory)); return TRUE; } @@ -1353,17 +1220,15 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_directory_exists(const char * path_in #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_get_file_size(const char* filename_in, size_t* file_size_out) -{ - if (filename_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_get_file_size(const char *filename_in, size_t *file_size_out) { + if (filename_in == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) pal_utf16_string path_in_utf16_string(filename_in); - auto* const h_file = CreateFile(path_in_utf16_string.data(), + auto *const h_file = CreateFile(path_in_utf16_string.data(), GENERIC_READ, FILE_SHARE_READ, nullptr, @@ -1371,8 +1236,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_get_file_size(const char* filename_in FILE_ATTRIBUTE_NORMAL, nullptr); - if (h_file == INVALID_HANDLE_VALUE) - { + if (h_file == INVALID_HANDLE_VALUE) { return FALSE; } @@ -1382,9 +1246,8 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_get_file_size(const char* filename_in return TRUE; #elif defined(PAL_PLATFORM_LINUX) - struct stat st = { 0 }; - if (stat(filename_in, &st) == 0) - { + struct stat st = {0}; + if (stat(filename_in, &st) == 0) { *file_size_out = st.st_size; return TRUE; } @@ -1394,35 +1257,32 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_get_file_size(const char* filename_in #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_read_file(const char *filename_in, char **bytes_out, size_t *bytes_read_out) -{ - if (filename_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION +pal_fs_read_file(const char *filename_in, char **bytes_out, size_t *bytes_read_out) { + if (filename_in == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) pal_utf16_string path_in_utf16_string(filename_in); - auto* const h_file = CreateFile(path_in_utf16_string.data(), + auto *const h_file = CreateFile(path_in_utf16_string.data(), GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); - if (h_file == INVALID_HANDLE_VALUE) - { + if (h_file == INVALID_HANDLE_VALUE) { return FALSE; } LARGE_INTEGER bytes_to_read_li; - if(0 == GetFileSizeEx(h_file, &bytes_to_read_li)) - { + if (0 == GetFileSizeEx(h_file, &bytes_to_read_li)) { LOGE << "Failed to get file size for filename: " << path_in_utf16_string << ". Error code: " << GetLastError(); assert(TRUE == CloseHandle(h_file)); - return FALSE; + return FALSE; } const auto bytes_to_read = static_cast(bytes_to_read_li.QuadPart); @@ -1433,36 +1293,30 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_read_file(const char *filename_in, ch char read_buffer[read_buffer_size]; bool readfile_success; - do - { + do { // https://docs.microsoft.com/en-us/windows/win32/fileio/testing-for-the-end-of-a-file readfile_success = TRUE == ReadFile(h_file, read_buffer, read_buffer_size, &read_buffer_bytes_read, nullptr); - if(read_buffer_bytes_read > 0) - { - assert(read_offset < bytes_to_read); + if (read_buffer_bytes_read > 0) { + assert(read_offset < bytes_to_read); - if (read_offset == 0) - { + if (read_offset == 0) { *bytes_out = new char[bytes_to_read]; - if (bytes_to_read < read_buffer_size) - { + if (bytes_to_read < read_buffer_size) { std::memcpy(*bytes_out, &read_buffer, read_buffer_bytes_read); read_offset = read_buffer_bytes_read; continue; } - } + } - std::memcpy(*bytes_out + read_offset, &read_buffer[0], read_buffer_bytes_read * sizeof read_buffer[0]); - read_offset += read_buffer_bytes_read; + std::memcpy(*bytes_out + read_offset, &read_buffer[0], read_buffer_bytes_read * sizeof read_buffer[0]); + read_offset += read_buffer_bytes_read; } - } while(readfile_success && read_buffer_bytes_read > 0); + } while (readfile_success && read_buffer_bytes_read > 0); assert(TRUE == CloseHandle(h_file)); - if (read_offset != bytes_to_read) - { - if (read_offset > 0) - { + if (read_offset != bytes_to_read) { + if (read_offset > 0) { delete[] bytes_out; } return FALSE; @@ -1473,8 +1327,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_read_file(const char *filename_in, ch return TRUE; #elif defined(PAL_PLATFORM_LINUX) auto fp = fopen(filename_in, "rb"); - if (fp == nullptr) - { + if (fp == nullptr) { return FALSE; } @@ -1496,10 +1349,8 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_read_file(const char *filename_in, ch #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_mkdir(const char* directory_in, pal_mode_t mode_in) -{ - if (directory_in == nullptr || mode_in <= 0) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_mkdir(const char *directory_in, pal_mode_t mode_in) { + if (directory_in == nullptr || mode_in <= 0) { return FALSE; } @@ -1507,48 +1358,43 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_mkdir(const char* directory_in, pal_m PAL_UNUSED(mode_in); pal_utf16_string directory_in_utf16_string(directory_in); const auto status = CreateDirectory(directory_in_utf16_string.data(), nullptr); - if (status == 0) - { - LOGE << "Error creating directory: " << directory_in_utf16_string << ". Status: " << status << ". Error code: " << GetLastError(); + if (status == 0) { + LOGE << "Error creating directory: " << directory_in_utf16_string << ". Status: " << status << ". Error code: " + << GetLastError(); return FALSE; } return TRUE; #else const auto status = mkdir(directory_in, mode_in); - if (status != 0) - { - LOGE << "Error creating directory: " << directory_in << ". Mode: " << mode_in << ". Errno: " << errno << ". Error code: " << std::strerror(errno); + if (status != 0) { + LOGE << "Error creating directory: " << directory_in << ". Mode: " << mode_in << ". Errno: " << errno << + ". Error code: " << std::strerror(errno); return FALSE; } return TRUE; #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_mkdirp(const char *directory_in, pal_mode_t mode_in) -{ - if (directory_in == nullptr || mode_in <= 0) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_mkdirp(const char *directory_in, pal_mode_t mode_in) { + if (directory_in == nullptr || mode_in <= 0) { return FALSE; } - const auto directory_in_normalized = std::make_unique(new char); - if (!pal_path_normalize(directory_in, directory_in_normalized.get())) - { + const auto directory_in_normalized = std::make_unique(new char); + if (!pal_path_normalize(directory_in, directory_in_normalized.get())) { return FALSE; } - const auto* const directory_sep = PAL_DIRECTORY_SEPARATOR_STR; + const auto *const directory_sep = PAL_DIRECTORY_SEPARATOR_STR; const auto directory_in_str = std::string(*directory_in_normalized); - const auto expand_paths = [&directory_in_str, &directory_sep]() - { + const auto expand_paths = [&directory_in_str, &directory_sep]() { auto last_index = directory_in_str.find_first_not_of(directory_sep, 0); auto current_index = directory_in_str.find_first_of(directory_sep, last_index); auto paths = std::vector(); while (std::string::npos != current_index - || std::string::npos != last_index) - { + || std::string::npos != last_index) { const auto path = directory_in_str.substr(0, current_index); paths.emplace_back(path); @@ -1561,15 +1407,12 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_mkdirp(const char *directory_in, pal_ auto directories_created = 0; const auto paths = expand_paths(); - for (const auto& path : paths) - { - if (pal_fs_directory_exists(path.c_str())) - { + for (const auto &path: paths) { + if (pal_fs_directory_exists(path.c_str())) { continue; } - if (!pal_fs_mkdir(path.c_str(), mode_in)) - { + if (!pal_fs_mkdir(path.c_str(), mode_in)) { return FALSE; } @@ -1579,60 +1422,53 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_mkdirp(const char *directory_in, pal_ return directories_created > 0 ? TRUE : FALSE; } -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_rmfile(const char* filename_in) -{ - if (filename_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_rmfile(const char *filename_in) { + if (filename_in == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) pal_utf16_string filename_in_utf16_string(filename_in); const auto status = DeleteFile(filename_in_utf16_string.data()); - if (status == 0) - { + if (status == 0) { LOGE << "Error removing file: " << filename_in_utf16_string << ". Error code: " << GetLastError(); return FALSE; } return TRUE; #elif defined(PAL_PLATFORM_LINUX) const auto status = remove(filename_in); - if (status != 0) - { - LOGE << "Error removing file: " << filename_in << ". Errno: " << errno << ". Error code: " << std::strerror(errno); + if (status != 0) { + LOGE << "Error removing file: " << filename_in << ". Errno: " << errno << ". Error code: " << + std::strerror(errno); return FALSE; } return TRUE; -#else +#else return FALSE; #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_rmdir(const char* directory_in, BOOL recursive) -{ - if (directory_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_rmdir(const char *directory_in, BOOL recursive) { + if (directory_in == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) pal_utf16_string directory_in_utf16_string(directory_in); - if (!recursive) - { + if (!recursive) { const auto status = RemoveDirectory(directory_in_utf16_string.data()); - if (status == 0) - { - LOGE << "Error removing directory: " << directory_in_utf16_string << ". Status: " << status << ". Error code: " << GetLastError(); + if (status == 0) { + LOGE << "Error removing directory: " << directory_in_utf16_string << ". Status: " << status << + ". Error code: " << GetLastError(); return FALSE; } return TRUE; } #elif defined(PAL_PLATFORM_LINUX) - if (!recursive) - { + if (!recursive) { const auto status = rmdir(directory_in); - if (status != 0) - { - LOGE << "Error removing directory: " << directory_in << ". Errno: " << errno << ". Error code: " << std::strerror(errno); + if (status != 0) { + LOGE << "Error removing directory: " << directory_in << ". Errno: " << errno << ". Error code: " << + std::strerror(errno); return FALSE; } return TRUE; @@ -1641,13 +1477,11 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_rmdir(const char* directory_in, BOOL return FALSE; #endif - char** files_array = nullptr; + char **files_array = nullptr; size_t files_array_len = 0u; - if (pal_fs_list_files(directory_in, nullptr, nullptr, &files_array, &files_array_len)) - { + if (pal_fs_list_files(directory_in, nullptr, nullptr, &files_array, &files_array_len)) { std::vector files(files_array, files_array + files_array_len); - for (const auto &filename : files) - { + for (const auto &filename: files) { pal_fs_rmfile(filename.c_str()); } @@ -1656,11 +1490,10 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_rmdir(const char* directory_in, BOOL files_array_len = 0; } - char** directories_array = nullptr; + char **directories_array = nullptr; size_t directories_array_len = 0u; if (!pal_fs_list_directories(directory_in, nullptr, nullptr, &directories_array, &directories_array_len) - || directories_array_len <= 0) - { + || directories_array_len <= 0) { return pal_fs_rmdir(directory_in, FALSE); } @@ -1670,10 +1503,8 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_rmdir(const char* directory_in, BOOL directories_array = nullptr; directories_array_len = 0; - for (const auto &directory : directories) - { - if (!pal_fs_rmdir(directory.c_str(), TRUE)) - { + for (const auto &directory: directories) { + if (!pal_fs_rmdir(directory.c_str(), TRUE)) { return FALSE; } } @@ -1681,45 +1512,42 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_rmdir(const char* directory_in, BOOL return pal_fs_rmdir(directory_in, FALSE); } -PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_write(const char* filename_in, const char* data_in, const size_t data_len_in) -{ +PAL_API BOOL PAL_CALLING_CONVENTION +pal_fs_write(const char *filename_in, const char *data_in, const size_t data_len_in) { if (filename_in == nullptr - || data_in == nullptr) - { + || data_in == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) pal_utf16_string filename_in_utf16_string(filename_in); - auto* const h_file = CreateFile(filename_in_utf16_string.data(), - GENERIC_WRITE, // open for writing - FILE_SHARE_READ, // allow read while writing - nullptr, // default security - CREATE_ALWAYS, // open existing file or create a new file - FILE_ATTRIBUTE_NORMAL, // normal file - nullptr); // no attr. template + auto *const h_file = CreateFile(filename_in_utf16_string.data(), + GENERIC_WRITE, // open for writing + FILE_SHARE_READ, // allow read while writing + nullptr, // default security + CREATE_ALWAYS, // open existing file or create a new file + FILE_ATTRIBUTE_NORMAL, // normal file + nullptr); // no attr. template - if(h_file == INVALID_HANDLE_VALUE) - { + if (h_file == INVALID_HANDLE_VALUE) { return FALSE; } DWORD bytes_written; - const auto success = WriteFile( - h_file, // open file handle - data_in, // start of data to write - data_len_in, // number of bytes to write - &bytes_written, // number of bytes that were written - nullptr); // no overlapped structure + const auto success = WriteFile( + h_file, // open file handle + data_in, // start of data to write + data_len_in, // number of bytes to write + &bytes_written, // number of bytes that were written + nullptr); // no overlapped structure CloseHandle(h_file); return success == TRUE && bytes_written == data_len_in ? TRUE : FALSE; #elif defined(PAL_PLATFORM_LINUX) const auto h_file = fopen(filename_in, "wb"); - if(h_file == nullptr) - { + if (h_file == nullptr) { return FALSE; } @@ -1727,8 +1555,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_write(const char* filename_in, const fclose(h_file); - if(bytes_written == data_len_in) - { + if (bytes_written == data_len_in) { return TRUE; } @@ -1738,35 +1565,30 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_fs_write(const char* filename_in, const #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_path_normalize(const char * path_in, char ** path_normalized_out) -{ - if (path_in == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_path_normalize(const char *path_in, char **path_normalized_out) { + if (path_in == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) pal_utf16_string path_in_utf16_string(path_in); - if (pal_is_windows_8_or_greater()) - { + if (pal_is_windows_8_or_greater()) { pal_module pathcch_module("api-ms-win-core-path-l1-1-0.dll"); - if (!pathcch_module.is_loaded()) - { - LOGE << "Failed to load: " <(PathCchCanonicalizeExFnName); - if (path_cch_canonicalize_fn == nullptr) - { + if (path_cch_canonicalize_fn == nullptr) { LOGE << "Failed to load function: " << PathCchCanonicalizeExFnName; return FALSE; } @@ -1779,14 +1601,13 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_normalize(const char * path_in, cha std::vector buffer(PAL_MAX_PATH_UNICODE); HRESULT const hr = path_cch_canonicalize_fn(buffer.data(), - buffer.size(), - path_in_utf16_string.data(), PATHCCH_ALLOW_LONG_PATHS); + buffer.size(), + path_in_utf16_string.data(), PATHCCH_ALLOW_LONG_PATHS); - if (hr != S_OK) - { + if (hr != S_OK) { LOGE << PathCchCanonicalizeExFnName << " failed to normalize path. " - << "Path: " << path_in_utf16_string << ". " - << "Error message: " << std::system_category().message(hr); + << "Path: " << path_in_utf16_string << ". " + << "Error message: " << std::system_category().message(hr); return FALSE; } @@ -1797,11 +1618,10 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_normalize(const char * path_in, cha pal_utf16_string path_normalized_utf16_string(PAL_MAX_PATH); const auto len = GetFullPathName(path_in_utf16_string.data(), - static_cast(path_normalized_utf16_string.size()), - path_normalized_utf16_string.data(), nullptr); + static_cast(path_normalized_utf16_string.size()), + path_normalized_utf16_string.data(), nullptr); - if (len == 0 || path_normalized_utf16_string.size() < len) - { + if (len == 0 || path_normalized_utf16_string.size() < len) { LOGE << "GetFullPathName failed to normalize path. " << "Path: " << path_in_utf16_string << ". " << "Error code: " << GetLastError(); @@ -1812,15 +1632,12 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_normalize(const char * path_in, cha #elif defined(PAL_PLATFORM_LINUX) std::string path_in_str(path_in); - if(path_in_str.empty()) - { + if (path_in_str.empty()) { return FALSE; } - const auto canonicalize_path = [](const std::string& path) - { - if (path.empty()) - { + const auto canonicalize_path = [](const std::string &path) { + if (path.empty()) { return path; } @@ -1832,14 +1649,12 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_normalize(const char * path_in, cha const auto dot_dot = std::string(".."); const auto starts_with_slash = path.front() == forward[0]; - if(path.size() == 1 - && starts_with_slash) - { + if (path.size() == 1 + && starts_with_slash) { return forward; } - do - { + do { const auto path_components_len = path_components.size(); const auto current = next + 1; @@ -1849,27 +1664,22 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_normalize(const char * path_in, cha // Skip empty (preserve initial) if (path_component.empty() - && path_components_len > 0) - { + && path_components_len > 0) { continue; } // Skip . (preserve initial) if (path_component == dot - && path_components_len > 0) - { + && path_components_len > 0) { continue; } - if (path_component == dot_dot && path_components_len > 0) - { + if (path_component == dot_dot && path_components_len > 0) { // Ignore if .. follows initial / - if (path_components.back().empty()) - { + if (path_components.back().empty()) { continue; } - if (path_components.back() != dot_dot) - { + if (path_components.back() != dot_dot) { path_components.pop_back(); continue; } @@ -1879,22 +1689,17 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_normalize(const char * path_in, cha } while (next != std::string::npos); std::stringstream buffer; - for(const auto& v : path_components) - { + for (const auto &v: path_components) { buffer << v << forward; } auto normalized_path = buffer.str(); - if(normalized_path.empty()) - { - if(starts_with_slash) - { + if (normalized_path.empty()) { + if (starts_with_slash) { normalized_path = forward; } - } else if(normalized_path.size() > 1) - { - if(normalized_path.back() == forward[0]) - { + } else if (normalized_path.size() > 1) { + if (normalized_path.back() == forward[0]) { normalized_path.pop_back(); } } @@ -1903,8 +1708,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_normalize(const char * path_in, cha }; const auto path_normalized = canonicalize_path(path_in_str); - if(path_normalized.empty()) - { + if (path_normalized.empty()) { return FALSE; } @@ -1916,11 +1720,9 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_normalize(const char * path_in, cha #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_path_combine(const char * path1, const char * path2, char ** path_out) -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_path_combine(const char *path1, const char *path2, char **path_out) { if (path1 == nullptr - || path2 == nullptr) - { + || path2 == nullptr) { return FALSE; } #if defined(PAL_PLATFORM_WINDOWS) @@ -1928,39 +1730,36 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_combine(const char * path1, const c pal_utf16_string path1_utf16_string(path1); pal_utf16_string path2_utf16_string(path2); - if (pal_is_windows_8_or_greater()) - { + if (pal_is_windows_8_or_greater()) { pal_module pathcch_module("api-ms-win-core-path-l1-1-0.dll"); - if (!pathcch_module.is_loaded()) - { + if (!pathcch_module.is_loaded()) { return FALSE; } - using PathCchCombineExFn = HRESULT(WINAPI*)(PWSTR pszPathOut, - size_t cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags); + using PathCchCombineExFn = HRESULT(WINAPI *)(PWSTR pszPathOut, + size_t cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore, + unsigned long dwFlags); const auto PATHCCH_ALLOW_LONG_PATHS = 0x00000001; const auto path_cch_combine_ex_fn = pathcch_module.bind("PathCchCombineEx"); - if (path_cch_combine_ex_fn == nullptr) - { + if (path_cch_combine_ex_fn == nullptr) { return FALSE; } std::vector buffer(PAL_MAX_PATH); const auto hr = path_cch_combine_ex_fn(buffer.data(), - buffer.size(), - path1_utf16_string.data(), - path2_utf16_string.data(), - PATHCCH_ALLOW_LONG_PATHS); + buffer.size(), + path1_utf16_string.data(), + path2_utf16_string.data(), + PATHCCH_ALLOW_LONG_PATHS); - if (!SUCCEEDED(hr)) - { + if (!SUCCEEDED(hr)) { LOGE << "PathCchCombineEx failed to combine paths. " - << "Path1: " << path1_utf16_string << ". " - << "Path2: " << path2_utf16_string << ". " - << "Error code: " << GetLastError(); + << "Path1: " << path1_utf16_string << ". " + << "Path2: " << path2_utf16_string << ". " + << "Error code: " << GetLastError(); return FALSE; } @@ -1970,12 +1769,11 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_combine(const char * path1, const c } wchar_t path_combined[PAL_MAX_PATH]; - if (nullptr == PathCombine(path_combined, path1_utf16_string.data(), path1_utf16_string.data())) - { + if (nullptr == PathCombine(path_combined, path1_utf16_string.data(), path1_utf16_string.data())) { LOGE << "PathCombine failed to combine paths. " - << "Path1: " << path1_utf16_string << ". " - << "Path2: " << path1_utf16_string << ". " - << "Error code: " << GetLastError(); + << "Path1: " << path1_utf16_string << ". " + << "Path2: " << path1_utf16_string << ". " + << "Error code: " << GetLastError(); return false; } @@ -1984,8 +1782,7 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_combine(const char * path1, const c return TRUE; #elif defined(PAL_PLATFORM_LINUX) char buffer[1024]; - if (nullptr == unix_path_combine(path1, path2, buffer)) - { + if (nullptr == unix_path_combine(path1, path2, buffer)) { return FALSE; } *path_out = strdup(buffer); @@ -1995,28 +1792,23 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_path_combine(const char * path1, const c #endif } -PAL_API BOOL PAL_CALLING_CONVENTION pal_str_endswith(const char * src, const char * str) -{ - if (src == nullptr || str == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_str_endswith(const char *src, const char *str) { + if (src == nullptr || str == nullptr) { return FALSE; } const auto value = std::string(src); const auto ending = std::string(str); - if (ending.size() > value.size()) - { + if (ending.size() > value.size()) { return FALSE; } return std::equal(ending.rbegin(), ending.rend(), value.rbegin()) ? TRUE : FALSE; } -PAL_API BOOL PAL_CALLING_CONVENTION pal_str_startswith(const char * src, const char * str) -{ - if (src == nullptr || str == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_str_startswith(const char *src, const char *str) { + if (src == nullptr || str == nullptr) { return FALSE; } @@ -2027,22 +1819,23 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_str_startswith(const char * src, const c return diff == 0; } -PAL_API BOOL PAL_CALLING_CONVENTION pal_str_iequals(const char* lhs, const char* rhs) -{ +PAL_API BOOL PAL_CALLING_CONVENTION pal_str_iequals(const char *lhs, const char *rhs) { auto str1(lhs == nullptr ? std::string() : lhs); auto str2(rhs == nullptr ? std::string() : rhs); - const auto equals = str1.size() == str2.size() && std::equal(str1.begin(), str1.end(), str2.begin(), [](char & c1, char & c2) { - return c1 == c2 || std::toupper(c1) == std::toupper(c2); - }) ? TRUE : FALSE; + const auto equals = str1.size() == str2.size() && std::equal(str1.begin(), str1.end(), str2.begin(), + [](char &c1, char &c2) { + return c1 == c2 || std::toupper(c1) == + std::toupper(c2); + }) + ? TRUE + : FALSE; return equals; } -PAL_API BOOL PAL_CALLING_CONVENTION pal_str_is_null_or_whitespace(const char* str) -{ - if (str == nullptr) - { +PAL_API BOOL PAL_CALLING_CONVENTION pal_str_is_null_or_whitespace(const char *str) { + if (str == nullptr) { return TRUE; } @@ -2056,4 +1849,4 @@ PAL_API BOOL PAL_CALLING_CONVENTION pal_str_is_null_or_whitespace(const char* st #else return FALSE; #endif -} +} \ No newline at end of file diff --git a/src/Snap.CoreRun.Pal/src/pal_module.cpp b/src/Snap.CoreRun.Pal/src/pal_module.cpp index b67e26d6..0f31962e 100644 --- a/src/Snap.CoreRun.Pal/src/pal_module.cpp +++ b/src/Snap.CoreRun.Pal/src/pal_module.cpp @@ -1,46 +1,37 @@ #include "pal/pal.hpp" #include "pal/pal_module.hpp" -pal_module::pal_module(const std::string& filename) : - m_module(nullptr), - m_filename(filename) -{ +pal_module::pal_module(const std::string &filename) : m_module(nullptr), + m_filename(filename) { pal_load_library(filename.c_str(), FALSE, &m_module); } -pal_module::~pal_module() -{ +pal_module::~pal_module() { const auto ptr = m_module; - if (ptr != nullptr) - { + if (ptr != nullptr) { pal_free_library(ptr); m_module = nullptr; } } -bool pal_module::is_loaded() const -{ +bool pal_module::is_loaded() const { return m_module != nullptr; } -const std::string& pal_module::get_filename() const -{ +const std::string &pal_module::get_filename() const { return m_filename; } -void* pal_module::_bind(const std::string& fn) const -{ - if (!this->is_loaded()) - { +void *pal_module::_bind(const std::string &fn) const { + if (!this->is_loaded()) { LOGE << "Failed to load method because module is not loaded. Method: " << fn << ". Module: " << get_filename(); return nullptr; } - void* ptr_fn = nullptr; - if (!pal_getprocaddress(m_module, fn.c_str(), &ptr_fn)) - { + void *ptr_fn = nullptr; + if (!pal_getprocaddress(m_module, fn.c_str(), &ptr_fn)) { LOGE << "Failed to load method: " << fn << ". Module: " << get_filename(); return nullptr; } return ptr_fn; -} +} \ No newline at end of file diff --git a/src/Snap.CoreRun.Pal/src/pal_semaphore.cpp b/src/Snap.CoreRun.Pal/src/pal_semaphore.cpp index 3b6584d9..66f5d6a2 100644 --- a/src/Snap.CoreRun.Pal/src/pal_semaphore.cpp +++ b/src/Snap.CoreRun.Pal/src/pal_semaphore.cpp @@ -1,9 +1,8 @@ #include "pal/pal.hpp" #include "pal/pal_semaphore.hpp" -pal_semaphore_machine_wide::pal_semaphore_machine_wide(const std::string& name) : - m_semaphore(nullptr), -#if defined(PAL_PLATFORM_WINDOWS) +pal_semaphore_machine_wide::pal_semaphore_machine_wide(const std::string &name) : m_semaphore(nullptr), +#if defined(PAL_PLATFORM_WINDOWS) m_semaphore_name("Global\\" + name) #else m_semaphore_name("/" + name) @@ -18,25 +17,25 @@ pal_semaphore_machine_wide::~pal_semaphore_machine_wide() { bool pal_semaphore_machine_wide::try_create() { #if defined(PAL_PLATFORM_WINDOWS) pal_utf16_string semaphore_name_utf16_string(m_semaphore_name); - auto* mutex = ::OpenMutex(SYNCHRONIZE, TRUE, semaphore_name_utf16_string.data()); - if(mutex != nullptr) { + auto *mutex = ::OpenMutex(SYNCHRONIZE, TRUE, semaphore_name_utf16_string.data()); + if (mutex != nullptr) { CloseHandle(mutex); return false; } // If name is not null and initiallyOwned is true, the calling thread owns the mutex only // if the named system mutex was created as a result of this call. - mutex = ::CreateMutex(nullptr, TRUE, semaphore_name_utf16_string.data()); + mutex = ::CreateMutex(nullptr, TRUE, semaphore_name_utf16_string.data()); if (mutex == nullptr || GetLastError() == ERROR_ALREADY_EXISTS) { return false; - } + } m_semaphore = mutex; return true; #elif defined(PAL_PLATFORM_LINUX) // http://man7.org/linux/man-pages/man7/sem_overview.7.html auto semaphore = sem_open(m_semaphore_name.c_str(), O_CREAT | O_EXCL, 0777, 0); - if(SEM_FAILED == semaphore) { + if (SEM_FAILED == semaphore) { return false; } m_semaphore = semaphore; @@ -47,8 +46,7 @@ bool pal_semaphore_machine_wide::try_create() { } bool pal_semaphore_machine_wide::release() { - if(m_semaphore == nullptr) - { + if (m_semaphore == nullptr) { return false; } #if defined(PAL_PLATFORM_WINDOWS) @@ -63,4 +61,4 @@ bool pal_semaphore_machine_wide::release() { #endif m_semaphore = nullptr; return true; -} +} \ No newline at end of file diff --git a/src/Snap.CoreRun.Pal/src/pal_string.cpp b/src/Snap.CoreRun.Pal/src/pal_string.cpp index 67a6e508..fd6c0e0d 100644 --- a/src/Snap.CoreRun.Pal/src/pal_string.cpp +++ b/src/Snap.CoreRun.Pal/src/pal_string.cpp @@ -6,10 +6,8 @@ #include // https://stackoverflow.com/a/10766913 -wchar_t * pal_str_widen(const char * utf8_str) -{ - if (utf8_str == nullptr || *utf8_str == '\0') - { +wchar_t *pal_str_widen(const char *utf8_str) { + if (utf8_str == nullptr || *utf8_str == '\0') { return nullptr; } @@ -18,8 +16,7 @@ wchar_t * pal_str_widen(const char * utf8_str) const size_t cch_utf8_max = INT_MAX - 1; size_t cch_utf8; const auto hr = ::StringCchLengthA(utf8_str, cch_utf8_max, &cch_utf8); - if (FAILED(hr)) - { + if (FAILED(hr)) { throw std::runtime_error("Unable to determine string character count."); } @@ -31,45 +28,41 @@ wchar_t * pal_str_widen(const char * utf8_str) // Get size of destination UTF-16 buffer, in WCHAR's const auto cch_utf16 = ::MultiByteToWideChar( - CP_UTF8, // convert from UTF-8 - MB_ERR_INVALID_CHARS, // error on invalid chars - utf8_str, // source UTF-8 string - cb_utf8, // total length of source UTF-8 string, - // in CHAR's (= bytes), including end-of-string \0 - nullptr, // unused - no conversion done in this step - 0 // request size of destination buffer, in WCHAR's + CP_UTF8, // convert from UTF-8 + MB_ERR_INVALID_CHARS, // error on invalid chars + utf8_str, // source UTF-8 string + cb_utf8, // total length of source UTF-8 string, + // in CHAR's (= bytes), including end-of-string \0 + nullptr, // unused - no conversion done in this step + 0 // request size of destination buffer, in WCHAR's ); - if (cch_utf16 == 0) - { + if (cch_utf16 == 0) { throw std::runtime_error("Unable to determine UTF-16 buffer size"); } - auto* const utf16_str = new wchar_t[cch_utf16]; + auto *const utf16_str = new wchar_t[cch_utf16]; // Do the conversion from UTF-8 to UTF-16 const auto utf16_str_len = ::MultiByteToWideChar( - CP_UTF8, // convert from UTF-8 - MB_ERR_INVALID_CHARS, // error on invalid chars - utf8_str, // source UTF-8 string - cb_utf8, // total length of source UTF-8 string, - // in CHAR's (= bytes), including end-of-string \0 - utf16_str, // destination buffer - cch_utf16 // size of destination buffer, in WCHAR's + CP_UTF8, // convert from UTF-8 + MB_ERR_INVALID_CHARS, // error on invalid chars + utf8_str, // source UTF-8 string + cb_utf8, // total length of source UTF-8 string, + // in CHAR's (= bytes), including end-of-string \0 + utf16_str, // destination buffer + cch_utf16 // size of destination buffer, in WCHAR's ); - if (utf16_str_len == 0) - { + if (utf16_str_len == 0) { throw std::runtime_error("Unable to convert from UTF-8 to UTF-16"); } return utf16_str; } -char * pal_str_narrow(const wchar_t * utf16_str) -{ - if (utf16_str == nullptr || *utf16_str == '\0') - { +char *pal_str_narrow(const wchar_t *utf16_str) { + if (utf16_str == nullptr || *utf16_str == '\0') { return nullptr; } @@ -78,8 +71,7 @@ char * pal_str_narrow(const wchar_t * utf16_str) const size_t cch_utf16_max = INT_MAX - 1; size_t cch_utf16; const auto hr = ::StringCchLengthW(utf16_str, cch_utf16_max, &cch_utf16); - if (FAILED(hr)) - { + if (FAILED(hr)) { throw std::runtime_error("Unable to determine string character count."); } @@ -93,43 +85,41 @@ char * pal_str_narrow(const wchar_t * utf16_str) // Get size of destination UTF-8 buffer, in CHAR's (= bytes) // const auto utf8_buffer_len = ::WideCharToMultiByte( - CP_UTF8, // convert to UTF-8 - dw_conversion_flags, // specify conversion behavior - utf16_str, // source UTF-16 string - static_cast(cch_utf16), // total source string length, in WCHAR's, - // including end-of-string \0 - nullptr, // unused - no conversion required in this step - 0, // request buffer size + CP_UTF8, // convert to UTF-8 + dw_conversion_flags, // specify conversion behavior + utf16_str, // source UTF-16 string + static_cast(cch_utf16), // total source string length, in WCHAR's, + // including end-of-string \0 + nullptr, // unused - no conversion required in this step + 0, // request buffer size nullptr, - nullptr // unused + nullptr // unused ); - if (utf8_buffer_len == 0) - { + if (utf8_buffer_len == 0) { throw std::runtime_error("Unable to determine UTF-8 buffer length"); } // Allocate destination buffer for UTF-8 string - auto* const utf8_buffer = new char[utf8_buffer_len]; + auto *const utf8_buffer = new char[utf8_buffer_len]; // Do the conversion from UTF-16 to UTF-8 const auto utf8_str_len = ::WideCharToMultiByte( - CP_UTF8, // convert to UTF-8 - dw_conversion_flags, // specify conversion behavior - utf16_str, // source UTF-16 string - static_cast(cch_utf16), // total source string length, in WCHAR's, - // including end-of-string \0 - utf8_buffer, // destination buffer - utf8_buffer_len, // destination buffer size, in bytes + CP_UTF8, // convert to UTF-8 + dw_conversion_flags, // specify conversion behavior + utf16_str, // source UTF-16 string + static_cast(cch_utf16), // total source string length, in WCHAR's, + // including end-of-string \0 + utf8_buffer, // destination buffer + utf8_buffer_len, // destination buffer size, in bytes nullptr, - nullptr // unused + nullptr // unused ); - if (utf8_str_len == 0) - { + if (utf8_str_len == 0) { throw std::runtime_error("Unable to convert from UTF-16 to UTF-8."); } return utf8_buffer; } -#endif +#endif \ No newline at end of file diff --git a/src/Snap.CoreRun.Pal/src/vendor/rcedit/rcedit.cpp b/src/Snap.CoreRun.Pal/src/vendor/rcedit/rcedit.cpp index 49d1f709..931051ae 100644 --- a/src/Snap.CoreRun.Pal/src/vendor/rcedit/rcedit.cpp +++ b/src/Snap.CoreRun.Pal/src/vendor/rcedit/rcedit.cpp @@ -8,11 +8,9 @@ #include "rcedit.hpp" -#pragma warning(disable : 4244 4267) - -namespace snap::rcedit -{ +#pragma warning(disable : 4244 4267) +namespace snap::rcedit { namespace { #pragma pack(push,2) typedef struct _GRPICONENTRY { @@ -56,7 +54,7 @@ namespace snap::rcedit #pragma pack(push,1) typedef struct _VS_VERSION_ROOT_INFO { WCHAR szKey[16]; - WORD Padding1[1]; + WORD Padding1[1]; VS_FIXEDFILEINFO Info; } VS_VERSION_ROOT_INFO; #pragma pack(pop) @@ -79,8 +77,11 @@ namespace snap::rcedit class ScopedFile { public: - ScopedFile(const WCHAR* path) - : file_(CreateFile(path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr)) {} + ScopedFile(const WCHAR *path) + : file_(CreateFile(path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, + nullptr)) { + } + ~ScopedFile() { CloseHandle(file_); } operator HANDLE() const { return file_; } @@ -100,8 +101,8 @@ namespace snap::rcedit } } - bool ResourceUpdater::Load(const WCHAR* filename) { - wchar_t abspath[MAX_PATH] = { 0 }; + bool ResourceUpdater::Load(const WCHAR *filename) { + wchar_t abspath[MAX_PATH] = {0}; if (_wfullpath(abspath, filename, MAX_PATH)) { module_ = LoadLibraryEx(abspath, nullptr, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); } else { @@ -120,13 +121,13 @@ namespace snap::rcedit return true; } - bool ResourceUpdater::SetIcon(const WCHAR* path, const LANGID& langId, UINT iconBundle) { - auto& pIcon = iconBundleMap_[langId].iconBundles[iconBundle]; + bool ResourceUpdater::SetIcon(const WCHAR *path, const LANGID &langId, UINT iconBundle) { + auto &pIcon = iconBundleMap_[langId].iconBundles[iconBundle]; if (!pIcon) { pIcon = std::make_unique(); } - auto& icon = *pIcon; + auto &icon = *pIcon; DWORD bytes; const ScopedFile file(path); @@ -134,7 +135,7 @@ namespace snap::rcedit return false; } - auto& header = icon.header; + auto &header = icon.header; if (!ReadFile(file, &header, 3 * sizeof(WORD), &bytes, nullptr)) { return false; } @@ -158,12 +159,12 @@ namespace snap::rcedit } icon.grpHeader.resize(3 * sizeof(WORD) + header.count * sizeof(GRPICONENTRY)); - auto* pGrpHeader = reinterpret_cast(icon.grpHeader.data()); + auto *pGrpHeader = reinterpret_cast(icon.grpHeader.data()); pGrpHeader->reserved = 0; pGrpHeader->type = 1; pGrpHeader->count = header.count; for (size_t i = 0; i < header.count; ++i) { - auto* const entry = pGrpHeader->entries + i; + auto *const entry = pGrpHeader->entries + i; entry->bitCount = 0; entry->bytesInRes = header.entries[i].bitCount; entry->bytesInRes2 = header.entries[i].bytesInRes; @@ -179,19 +180,19 @@ namespace snap::rcedit return true; } - bool ResourceUpdater::SetIcon(const WCHAR* path, const LANGID& langId) { + bool ResourceUpdater::SetIcon(const WCHAR *path, const LANGID &langId) { const auto iconBundle = iconBundleMap_.count(langId) ? iconBundleMap_[langId].iconBundles.begin()->first : 0u; return SetIcon(path, langId, iconBundle); } - bool ResourceUpdater::SetIcon(const WCHAR* path) { - const auto langId = iconBundleMap_.empty() ? kLangEnUs + bool ResourceUpdater::SetIcon(const WCHAR *path) { + const auto langId = iconBundleMap_.empty() + ? kLangEnUs : iconBundleMap_.begin()->first; return SetIcon(path, langId); } - bool ResourceUpdater::HasIcon() const - { + bool ResourceUpdater::HasIcon() const { return !iconBundleMap_.empty(); } @@ -207,35 +208,34 @@ namespace snap::rcedit return false; } - for (const auto& iLangIconInfoPair : iconBundleMap_) { + for (const auto &iLangIconInfoPair: iconBundleMap_) { const auto langId = iLangIconInfoPair.first; const auto maxIconId = iLangIconInfoPair.second.maxIconId; - for (const auto& iNameBundlePair : iLangIconInfoPair.second.iconBundles) { + for (const auto &iNameBundlePair: iLangIconInfoPair.second.iconBundles) { const auto bundleId = iNameBundlePair.first; - const auto& pIcon = iNameBundlePair.second; + const auto &pIcon = iNameBundlePair.second; if (!pIcon) { continue; } - auto& icon = *pIcon; + auto &icon = *pIcon; // update icon. if (!icon.grpHeader.empty()) { if (!UpdateResource(ru.Get(), RT_GROUP_ICON, MAKEINTRESOURCE(bundleId), - langId, icon.grpHeader.data(), icon.grpHeader.size())) { + langId, icon.grpHeader.data(), icon.grpHeader.size())) { return false; } for (size_t i = 0; i < icon.header.count; ++i) { if (!UpdateResource(ru.Get(), RT_ICON, MAKEINTRESOURCE(i + 1), - langId, icon.images[i].data(), icon.images[i].size())) { - + langId, icon.images[i].data(), icon.images[i].size())) { return false; } } for (size_t i = icon.header.count; i < maxIconId; ++i) { if (!UpdateResource(ru.Get(), RT_ICON, MAKEINTRESOURCE(i + 1), - langId, nullptr, 0)) { + langId, nullptr, 0)) { return false; } } @@ -247,21 +247,19 @@ namespace snap::rcedit } // static - BOOL CALLBACK ResourceUpdater::OnEnumResourceLanguage(HANDLE hModule, LPCWSTR lpszType, LPCWSTR lpszName, WORD wIDLanguage, LONG_PTR lParam) { - auto* instance = reinterpret_cast(lParam); + BOOL CALLBACK ResourceUpdater::OnEnumResourceLanguage(HANDLE hModule, LPCWSTR lpszType, LPCWSTR lpszName, + WORD wIDLanguage, LONG_PTR lParam) { + auto *instance = reinterpret_cast(lParam); auto iconId = 0u; auto maxIconId = 0u; if (IS_INTRESOURCE(lpszName) && IS_INTRESOURCE(lpszType)) { - if (lpszType == RT_ICON) - { + if (lpszType == RT_ICON) { iconId = reinterpret_cast(lpszName); maxIconId = instance->iconBundleMap_[wIDLanguage].maxIconId; if (iconId > maxIconId) { maxIconId = iconId; } - } - else if (lpszType == RT_GROUP_ICON) - { + } else if (lpszType == RT_GROUP_ICON) { iconId = reinterpret_cast(lpszName); instance->iconBundleMap_[wIDLanguage].iconBundles[iconId] = nullptr; } @@ -270,12 +268,14 @@ namespace snap::rcedit } // static - BOOL CALLBACK ResourceUpdater::OnEnumResourceName(HMODULE hModule, LPCWSTR lpszType, LPWSTR lpszName, LONG_PTR lParam) { - EnumResourceLanguages(hModule, lpszType, lpszName, reinterpret_cast(OnEnumResourceLanguage), lParam); + BOOL CALLBACK ResourceUpdater::OnEnumResourceName(HMODULE hModule, LPCWSTR lpszType, LPWSTR lpszName, + LONG_PTR lParam) { + EnumResourceLanguages(hModule, lpszType, lpszName, reinterpret_cast(OnEnumResourceLanguage), + lParam); return TRUE; } - ScopedResourceUpdater::ScopedResourceUpdater(const WCHAR* filename, bool deleteOld) + ScopedResourceUpdater::ScopedResourceUpdater(const WCHAR *filename, bool deleteOld) : handle_(BeginUpdateResource(filename, deleteOld)) { } @@ -294,13 +294,11 @@ namespace snap::rcedit return EndUpdate(true); } - bool ScopedResourceUpdater::EndUpdate(bool doesCommit) const - { + bool ScopedResourceUpdater::EndUpdate(bool doesCommit) const { const auto fDiscard = doesCommit ? FALSE : TRUE; const auto bResult = EndUpdateResource(handle_, fDiscard); auto e = GetLastError(); return bResult ? true : false; } - } -#endif +#endif \ No newline at end of file diff --git a/src/Snap.CoreRun.Pal/src/vendor/rcedit/rcedit.hpp b/src/Snap.CoreRun.Pal/src/vendor/rcedit/rcedit.hpp index 96049fd7..634194f8 100644 --- a/src/Snap.CoreRun.Pal/src/vendor/rcedit/rcedit.hpp +++ b/src/Snap.CoreRun.Pal/src/vendor/rcedit/rcedit.hpp @@ -15,9 +15,7 @@ #include -namespace snap::rcedit -{ - +namespace snap::rcedit { struct IconsValue { typedef struct _ICONENTRY { BYTE width; @@ -38,13 +36,13 @@ namespace snap::rcedit } ICONHEADER; ICONHEADER header; - std::vector> images; + std::vector > images; std::vector grpHeader; }; class ResourceUpdater { public: - typedef std::map> IconTable; + typedef std::map > IconTable; struct IconResInfo { UINT maxIconId = 0; @@ -54,17 +52,25 @@ namespace snap::rcedit typedef std::map IconTableMap; ResourceUpdater(); + ~ResourceUpdater(); - bool Load(const WCHAR* filename); - bool SetIcon(const WCHAR* path, const LANGID& langId, UINT iconBundle); - bool SetIcon(const WCHAR* path, const LANGID& langId); - bool SetIcon(const WCHAR* path); + bool Load(const WCHAR *filename); + + bool SetIcon(const WCHAR *path, const LANGID &langId, UINT iconBundle); + + bool SetIcon(const WCHAR *path, const LANGID &langId); + + bool SetIcon(const WCHAR *path); + bool HasIcon() const; + bool Commit(); static BOOL CALLBACK OnEnumResourceName(HMODULE hModule, LPCWSTR lpszType, LPWSTR lpszName, LONG_PTR lParam); - static BOOL CALLBACK OnEnumResourceLanguage(HANDLE hModule, LPCWSTR lpszType, LPCWSTR lpszName, WORD wIDLanguage, LONG_PTR lParam); + + static BOOL CALLBACK OnEnumResourceLanguage(HANDLE hModule, LPCWSTR lpszType, LPCWSTR lpszName, + WORD wIDLanguage, LONG_PTR lParam); HMODULE module_; std::wstring filename_; @@ -73,10 +79,12 @@ namespace snap::rcedit class ScopedResourceUpdater { public: - ScopedResourceUpdater(const WCHAR* filename, bool deleteOld); + ScopedResourceUpdater(const WCHAR *filename, bool deleteOld); + ~ScopedResourceUpdater(); HANDLE Get() const; + bool Commit(); private: @@ -85,6 +93,5 @@ namespace snap::rcedit HANDLE handle_; bool commited_ = false; }; - } -#endif +#endif \ No newline at end of file diff --git a/src/Snap.CoreRun.Pal/test/anyos.cpp b/src/Snap.CoreRun.Pal/test/anyos.cpp index 6d20d2cb..62eae66c 100644 --- a/src/Snap.CoreRun.Pal/test/anyos.cpp +++ b/src/Snap.CoreRun.Pal/test/anyos.cpp @@ -6,37 +6,30 @@ using json = nlohmann::json; using testutils = corerun::support::util::test_utils; -namespace -{ - TEST(PAL_GENERIC, pal_is_windows_8_or_greater_DoesNotSegfault) - { +namespace { + TEST(PAL_GENERIC, pal_is_windows_8_or_greater_DoesNotSegfault) { pal_is_windows_8_or_greater(); } - TEST(PAL_GENERIC, pal_is_windows_7_or_greater_DoesNotSegfault) - { + TEST(PAL_GENERIC, pal_is_windows_7_or_greater_DoesNotSegfault) { pal_is_windows_7_or_greater(); } - TEST(PAL_GENERIC, pal_set_icon_DoesNotSegfault) - { + TEST(PAL_GENERIC, pal_set_icon_DoesNotSegfault) { pal_set_icon(nullptr, nullptr); } - TEST(PAL_GENERIC, pal_has_icon_DoesNotSegfault) - { + TEST(PAL_GENERIC, pal_has_icon_DoesNotSegfault) { pal_has_icon(nullptr); } - TEST(PAL_GENERIC, pal_process_get_name_ReturnsThisProcessExeName) - { - const auto exe_name = std::make_unique(new char); + TEST(PAL_GENERIC, pal_process_get_name_ReturnsThisProcessExeName) { + const auto exe_name = std::make_unique(new char); EXPECT_TRUE(pal_process_get_name(exe_name.get())); EXPECT_TRUE(pal_str_startswith(*exe_name, "corerun_tests")); } - TEST(PAL_GENERIC, pal_process_is_running) - { + TEST(PAL_GENERIC, pal_process_is_running) { pal_pid_t pid; EXPECT_TRUE(pal_process_get_pid(&pid)); EXPECT_TRUE(pal_process_is_running(pid)); @@ -44,10 +37,8 @@ namespace pal_pid_t next_pid = 1000; auto process_is_running = TRUE; - while (process_is_running) - { - if (next_pid > 25000) - { + while (process_is_running) { + if (next_pid > 25000) { break; } @@ -58,191 +49,165 @@ namespace ASSERT_EQ(process_is_running, FALSE); } - TEST(PAL_GENERIC, pal_isdebuggerpresent_DoesNotSegfault) - { + TEST(PAL_GENERIC, pal_isdebuggerpresent_DoesNotSegfault) { pal_isdebuggerpresent(); } - TEST(PAL_GENERIC, pal_wait_for_debugger_DoesNotSegfault) - { - if (!pal_isdebuggerpresent()) - { + TEST(PAL_GENERIC, pal_wait_for_debugger_DoesNotSegfault) { + if (!pal_isdebuggerpresent()) { return; } EXPECT_TRUE(pal_wait_for_debugger()); } - TEST(PAL_GENERIC, pal_load_library_DoesNotSegFault) - { - void** instance = nullptr; + TEST(PAL_GENERIC, pal_load_library_DoesNotSegFault) { + void **instance = nullptr; EXPECT_FALSE(pal_load_library(nullptr, FALSE, instance)); EXPECT_EQ(instance, nullptr); } - TEST(PAL_GENERIC, pal_free_library_DoesNotSegfault) - { + TEST(PAL_GENERIC, pal_free_library_DoesNotSegfault) { EXPECT_FALSE(pal_free_library(nullptr)); } - TEST(PAL_GENERIC, pal_getprocaddress_DoesNotSegfault) - { - void** fn_ptr = nullptr; + TEST(PAL_GENERIC, pal_getprocaddress_DoesNotSegfault) { + void **fn_ptr = nullptr; EXPECT_FALSE(pal_getprocaddress(nullptr, nullptr, fn_ptr)); EXPECT_EQ(fn_ptr, nullptr); } - TEST(PAL_GENERIC, pal_set_icon_DoesNotSegFault) - { + TEST(PAL_GENERIC, pal_set_icon_DoesNotSegFault) { EXPECT_FALSE(pal_set_icon(nullptr, nullptr)); } - TEST(PAL_GENERIC, pal_process_get_pid_ReturnsValueGreaterThanZero) - { + TEST(PAL_GENERIC, pal_process_get_pid_ReturnsValueGreaterThanZero) { pal_pid_t pid; EXPECT_EQ(TRUE, pal_process_get_pid(&pid)); EXPECT_GT(pid, 0u); } - TEST(PAL_GENERIC, pal_is_elevated_DoesNotSegfault) - { + TEST(PAL_GENERIC, pal_is_elevated_DoesNotSegfault) { pal_is_elevated(); } - TEST(PAL_GENERIC, pal_process_is_running_ReturnsTrueForThisProcess) - { + TEST(PAL_GENERIC, pal_process_is_running_ReturnsTrueForThisProcess) { pal_pid_t pid; pal_process_get_pid(&pid); EXPECT_GT(pid, 0u); EXPECT_TRUE(pal_process_is_running(pid)); } - TEST(PAL_GENERIC, pal_sleep_ms_DoesNotSegFault) - { + TEST(PAL_GENERIC, pal_sleep_ms_DoesNotSegFault) { pal_sleep_ms(0); pal_sleep_ms(1); } - TEST(PAL_GENERIC, pal_is_unknown_os) - { + TEST(PAL_GENERIC, pal_is_unknown_os) { EXPECT_FALSE(pal_is_unknown_os()); } - TEST(PAL_ENV, pal_env_set_DoesNotSegfault) - { + TEST(PAL_ENV, pal_env_set_DoesNotSegfault) { EXPECT_FALSE(pal_env_set(nullptr, nullptr)); } - TEST(PAL_ENV, pal_env_set_NullptrDeletesVariable) - { + TEST(PAL_ENV, pal_env_set_NullptrDeletesVariable) { const auto random_variable = testutils::build_random_str(); EXPECT_TRUE(pal_env_set(random_variable.c_str(), nullptr)); - const auto value = std::make_unique(new char); + const auto value = std::make_unique(new char); EXPECT_FALSE(pal_env_get(random_variable.c_str(), value.get())); } - TEST(PAL_ENV, pal_env_set_Overwrite) - { + TEST(PAL_ENV, pal_env_set_Overwrite) { const auto random_variable = testutils::build_random_str(); EXPECT_TRUE(pal_env_set(random_variable.c_str(), "TEST")); EXPECT_TRUE(pal_env_set(random_variable.c_str(), "TEST2")); - const auto value = std::make_unique(new char); + const auto value = std::make_unique(new char); EXPECT_TRUE(pal_env_get(random_variable.c_str(), value.get())); EXPECT_STREQ(*value, "TEST2"); } - TEST(PAL_ENV, pal_env_set) - { + TEST(PAL_ENV, pal_env_set) { const auto random_variable = testutils::build_random_str(); const auto random_text = testutils::build_random_str(); EXPECT_TRUE(pal_env_set(random_variable.c_str(), random_text.c_str())); - const auto value = std::make_unique(new char); + const auto value = std::make_unique(new char); EXPECT_TRUE(pal_env_get(random_variable.c_str(), value.get())); EXPECT_STREQ(*value, random_text.c_str()); } - TEST(PAL_ENV, pal_env_get_variable_DoesNotSegFault) - { - char** value = nullptr; + TEST(PAL_ENV, pal_env_get_variable_DoesNotSegFault) { + char **value = nullptr; EXPECT_FALSE(pal_env_get(nullptr, value)); EXPECT_EQ(value, nullptr); } - TEST(PAL_ENV, pal_env_get_bool_DoesNotSegFault) - { + TEST(PAL_ENV, pal_env_get_bool_DoesNotSegFault) { EXPECT_FALSE(pal_env_get_bool(nullptr)); } - TEST(PAL_ENV, pal_env_expand_str_DoesNotSegfault) - { - char** value = nullptr; + TEST(PAL_ENV, pal_env_expand_str_DoesNotSegfault) { + char **value = nullptr; EXPECT_FALSE(pal_env_expand_str(nullptr, value)); EXPECT_EQ(value, nullptr); } - TEST(PAL_FS, pal_fs_chmod_DoesNotSegfault) - { + TEST(PAL_FS, pal_fs_chmod_DoesNotSegfault) { EXPECT_FALSE(pal_fs_chmod(nullptr, 0)); } - TEST(PAL_FS, pal_fs_file_exists_ReturnsFalseIfDirectory) - { + TEST(PAL_FS, pal_fs_file_exists_ReturnsFalseIfDirectory) { const auto working_dir = testutils::get_process_cwd(); ASSERT_FALSE(pal_fs_file_exists(working_dir.c_str())); } - TEST(PAL_FS, pal_fs_file_exists_ReturnsTrueWhenAbsolutePath) - { - const auto exe_abs_path = std::make_unique(new char); + TEST(PAL_FS, pal_fs_file_exists_ReturnsTrueWhenAbsolutePath) { + const auto exe_abs_path = std::make_unique(new char); EXPECT_TRUE(pal_process_get_real_path(exe_abs_path.get())); EXPECT_TRUE(pal_fs_file_exists(*exe_abs_path)); } - TEST(PAL_FS, pal_fs_list_directories_DoesNotSegfault) - { - char** directories_array = nullptr; + TEST(PAL_FS, pal_fs_list_directories_DoesNotSegfault) { + char **directories_array = nullptr; size_t directories_len = 0u; EXPECT_FALSE(pal_fs_list_directories(nullptr, nullptr, nullptr, &directories_array, &directories_len)); EXPECT_EQ(directories_array, nullptr); EXPECT_EQ(directories_len, 0u); } - TEST(PAL_FS, pal_fs_list_directories_ReturnsDirectoriesInCurrentWorkingDirectory) - { + TEST(PAL_FS, pal_fs_list_directories_ReturnsDirectoriesInCurrentWorkingDirectory) { const auto working_dir = testutils::get_process_cwd(); const auto random_dir = testutils::mkdir_random(working_dir); ASSERT_TRUE(pal_fs_directory_exists(random_dir.c_str())); - char** directories_array = nullptr; + char **directories_array = nullptr; size_t directories_len = 0u; - EXPECT_TRUE(pal_fs_list_directories(working_dir.c_str(), nullptr, nullptr, &directories_array, &directories_len)); + EXPECT_TRUE( + pal_fs_list_directories(working_dir.c_str(), nullptr, nullptr, &directories_array, &directories_len)); EXPECT_NE(directories_array, nullptr); EXPECT_GT(directories_len, 0u); std::vector directories(directories_array, directories_array + directories_len); EXPECT_EQ(directories.size(), directories_len); - for (const auto directory : directories) - { + for (const auto directory: directories) { EXPECT_FALSE(directory.empty()); EXPECT_TRUE(pal_fs_directory_exists(directory.c_str())); EXPECT_FALSE(pal_fs_file_exists(directory.c_str())); } } - TEST(PAL_FS, pal_fs_list_files_DoesNotSegfault) - { - char** files = nullptr; + TEST(PAL_FS, pal_fs_list_files_DoesNotSegfault) { + char **files = nullptr; size_t files_len = 0u; EXPECT_FALSE(pal_fs_list_files(nullptr, nullptr, nullptr, &files, &files_len)); EXPECT_EQ(files, nullptr); EXPECT_EQ(files_len, 0u); } - TEST(PAL_FS, pal_fs_list_files_ReturnsAListOfFilesInCurrentWorkingDirectory) - { + TEST(PAL_FS, pal_fs_list_files_ReturnsAListOfFilesInCurrentWorkingDirectory) { const auto working_dir = testutils::get_process_cwd(); - char** files_array = nullptr; + char **files_array = nullptr; size_t files_len = 0u; EXPECT_TRUE(pal_fs_list_files(working_dir.c_str(), nullptr, nullptr, &files_array, &files_len)); EXPECT_NE(files_array, nullptr); @@ -251,91 +216,85 @@ namespace std::vector files(files_array, files_array + files_len); EXPECT_EQ(files.size(), files_len); - for (const auto file : files) - { + for (const auto file: files) { EXPECT_FALSE(file.empty()); EXPECT_TRUE(pal_fs_file_exists(file.c_str())); EXPECT_FALSE(pal_fs_directory_exists(file.c_str())); } } - TEST(PAL_FS, pal_process_get_real_path) - { - const auto this_process_real_path = std::make_unique(new char); + TEST(PAL_FS, pal_process_get_real_path) { + const auto this_process_real_path = std::make_unique(new char); EXPECT_TRUE(pal_process_get_real_path(this_process_real_path.get())); EXPECT_NE(*this_process_real_path, nullptr); } - TEST(PAL_FS, pal_fs_directory_exists_ReturnsTrueThatThisWorkingDirectoryExists) - { + TEST(PAL_FS, pal_fs_directory_exists_ReturnsTrueThatThisWorkingDirectoryExists) { const auto working_dir = testutils::get_process_cwd(); EXPECT_TRUE(pal_fs_directory_exists(working_dir.c_str())); } - TEST(PAL_FS_WINDOWS, pal_fs_directory_exists_TrailingSlash) - { + TEST(PAL_FS_WINDOWS, pal_fs_directory_exists_TrailingSlash) { const auto working_dir = testutils::get_process_cwd() + PAL_DIRECTORY_SEPARATOR_STR; ASSERT_TRUE(pal_fs_directory_exists(working_dir.c_str())); } - TEST(PAL_FS, pal_fs_get_file_size_ReturnsFalseWhenFileDoesNotExist) - { + TEST(PAL_FS, pal_fs_get_file_size_ReturnsFalseWhenFileDoesNotExist) { const auto filename = testutils::build_random_filename(); size_t file_size = 0; EXPECT_FALSE(pal_fs_get_file_size(filename.c_str(), &file_size)); EXPECT_EQ(file_size, 0u); } - TEST(PAL_FS, pal_fs_get_file_size_ReturnsFalseWhenDirectoryDoesNotExist) - { + TEST(PAL_FS, pal_fs_get_file_size_ReturnsFalseWhenDirectoryDoesNotExist) { const auto dir_name = testutils::build_random_dirname(); size_t file_size = 0; EXPECT_FALSE(pal_fs_get_file_size(dir_name.c_str(), &file_size)); EXPECT_EQ(file_size, 0u); } - TEST(PAL_FS, pal_fs_get_file_size_ReturnsAValueGreaterThanZero) - { + TEST(PAL_FS, pal_fs_get_file_size_ReturnsAValueGreaterThanZero) { const auto exe_abs_path = testutils::get_process_real_path(); size_t file_size = 0; EXPECT_TRUE(pal_fs_get_file_size(exe_abs_path.c_str(), &file_size)); EXPECT_GT(file_size, 0u); } - TEST(PAL_FS, pal_fs_read_file_CanRepeatedlyReadAndWrite) - { + TEST(PAL_FS, pal_fs_read_file_CanRepeatedlyReadAndWrite) { const json doc_before = { {"pi", 3.141}, {"happy", true}, {"name", "Niels"}, {"nothing", nullptr}, - {"answer", { - {"everything", 42} - }}, + { + "answer", { + {"everything", 42} + } + }, {"list", {1, 0, 2}}, - {"object", { - {"currency", "USD"}, - {"value", 42.99} - }} + { + "object", { + {"currency", "USD"}, + {"value", 42.99} + } + } }; const auto json = doc_before.dump(); const auto working_dir = testutils::mkdir_random(testutils::get_process_cwd()); - const auto test_filename = testutils::path_combine(working_dir, "test.json"); + const auto test_filename = testutils::path_combine(working_dir, "test.json"); - for(auto i = 0; i < 10; i++) - { + for (auto i = 0; i < 10; i++) { ASSERT_TRUE(pal_fs_write(test_filename.c_str(), json.c_str(), json.size())); - char* data = nullptr; + char *data = nullptr; size_t data_len = 0; ASSERT_TRUE(pal_fs_read_file(test_filename.c_str(), &data, &data_len)); ASSERT_TRUE(data != nullptr); ASSERT_TRUE(data_len > 0); - for (auto buffer_index = 0u; buffer_index < data_len; buffer_index++) - { + for (auto buffer_index = 0u; buffer_index < data_len; buffer_index++) { ASSERT_NE(&data[buffer_index], nullptr); } @@ -344,31 +303,26 @@ namespace const auto json_after = json::parse(data); ASSERT_STREQ(json.c_str(), json_after.dump().c_str()); } - } - - TEST(PAL_FS, pal_fs_mkdir_DoesNotSegfault) - { + + TEST(PAL_FS, pal_fs_mkdir_DoesNotSegfault) { EXPECT_FALSE(pal_fs_mkdir(nullptr, 0)); } - TEST(PAL_FS, pal_fs_mkdirp_DoesNotSegfault) - { + TEST(PAL_FS, pal_fs_mkdirp_DoesNotSegfault) { EXPECT_FALSE(pal_fs_mkdirp(nullptr, 0)); } - TEST(PAL_FS, pal_fs_mkdirp) - { + TEST(PAL_FS, pal_fs_mkdirp) { const auto working_dir = testutils::get_process_cwd(); const auto test_path = - working_dir + - PAL_DIRECTORY_SEPARATOR_C + "a" + - PAL_DIRECTORY_SEPARATOR_C + "b" + - PAL_DIRECTORY_SEPARATOR_C + "c"; + working_dir + + PAL_DIRECTORY_SEPARATOR_C + "a" + + PAL_DIRECTORY_SEPARATOR_C + "b" + + PAL_DIRECTORY_SEPARATOR_C + "c"; - if (pal_fs_directory_exists(test_path.c_str())) - { + if (pal_fs_directory_exists(test_path.c_str())) { pal_fs_rmdir(test_path.c_str(), TRUE); } @@ -376,19 +330,17 @@ namespace ASSERT_TRUE(pal_fs_directory_exists(test_path.c_str())); } - TEST(PAL_FS, pal_fs_mkdirpTrailingDirectorySeparator) - { + TEST(PAL_FS, pal_fs_mkdirpTrailingDirectorySeparator) { const auto working_dir = testutils::get_process_cwd(); const auto test_path = - working_dir + - PAL_DIRECTORY_SEPARATOR_C + "a" + - PAL_DIRECTORY_SEPARATOR_C + "b" + - PAL_DIRECTORY_SEPARATOR_C + "c" + - PAL_DIRECTORY_SEPARATOR_C; - - if (pal_fs_directory_exists(test_path.c_str())) - { + working_dir + + PAL_DIRECTORY_SEPARATOR_C + "a" + + PAL_DIRECTORY_SEPARATOR_C + "b" + + PAL_DIRECTORY_SEPARATOR_C + "c" + + PAL_DIRECTORY_SEPARATOR_C; + + if (pal_fs_directory_exists(test_path.c_str())) { pal_fs_rmdir(test_path.c_str(), TRUE); } @@ -396,21 +348,19 @@ namespace ASSERT_TRUE(pal_fs_directory_exists(test_path.c_str())); } - TEST(PAL_FS, pal_fs_mkdirpMultipleTrailingDirectorySeparators) - { + TEST(PAL_FS, pal_fs_mkdirpMultipleTrailingDirectorySeparators) { const auto working_dir = testutils::mkdir_random(testutils::get_process_cwd()); const auto test_path = - working_dir + - PAL_DIRECTORY_SEPARATOR_C + "a" + - PAL_DIRECTORY_SEPARATOR_C + "b" + - PAL_DIRECTORY_SEPARATOR_C + "c" + - PAL_DIRECTORY_SEPARATOR_C + - PAL_DIRECTORY_SEPARATOR_C + - PAL_DIRECTORY_SEPARATOR_C + "d"; - - if (pal_fs_directory_exists(test_path.c_str())) - { + working_dir + + PAL_DIRECTORY_SEPARATOR_C + "a" + + PAL_DIRECTORY_SEPARATOR_C + "b" + + PAL_DIRECTORY_SEPARATOR_C + "c" + + PAL_DIRECTORY_SEPARATOR_C + + PAL_DIRECTORY_SEPARATOR_C + + PAL_DIRECTORY_SEPARATOR_C + "d"; + + if (pal_fs_directory_exists(test_path.c_str())) { pal_fs_rmdir(test_path.c_str(), TRUE); } @@ -418,20 +368,17 @@ namespace ASSERT_TRUE(pal_fs_directory_exists(test_path.c_str())); } - TEST(PAL_FS, pal_fs_mkdirp_ReturnsFalseIfDirectoryAlreadyExists) - { + TEST(PAL_FS, pal_fs_mkdirp_ReturnsFalseIfDirectoryAlreadyExists) { const auto working_dir = testutils::get_process_cwd(); ASSERT_FALSE(pal_fs_mkdirp(working_dir.c_str(), 0777)); } - TEST(PAL_FS, pal_pal_fs_rmdir_DoesNotSegfault) - { + TEST(PAL_FS, pal_pal_fs_rmdir_DoesNotSegfault) { EXPECT_FALSE(pal_fs_rmdir(nullptr, FALSE)); EXPECT_FALSE(pal_fs_rmdir(nullptr, TRUE)); } - TEST(PAL_FS, pal_pal_fs_rmdir_RemovesEmptyDirectory) - { + TEST(PAL_FS, pal_pal_fs_rmdir_RemovesEmptyDirectory) { const auto working_dir = testutils::get_process_cwd(); const auto empty_dir = testutils::mkdir_random(working_dir); EXPECT_TRUE(pal_fs_directory_exists(empty_dir.c_str())); @@ -439,8 +386,7 @@ namespace EXPECT_FALSE(pal_fs_directory_exists(empty_dir.c_str())); } - TEST(PAL_FS, pal_pal_fs_rmdir_RemovesDirectoryWithASingleFile) - { + TEST(PAL_FS, pal_pal_fs_rmdir_RemovesDirectoryWithASingleFile) { const auto working_dir = testutils::get_process_cwd(); const auto directory = testutils::mkdir_random(working_dir); const auto filename = testutils::mkfile(directory, "test.txt"); @@ -451,8 +397,7 @@ namespace EXPECT_FALSE(pal_fs_directory_exists(directory.c_str())); } - TEST(PAL_FS, pal_pal_fs_rmdir_RemovesDirectoryWithMultipleFiles) - { + TEST(PAL_FS, pal_pal_fs_rmdir_RemovesDirectoryWithMultipleFiles) { const auto working_dir = testutils::get_process_cwd(); const auto directory = testutils::mkdir_random(working_dir); const auto filename1 = testutils::mkfile(directory, "test.txt"); @@ -465,8 +410,7 @@ namespace EXPECT_FALSE(pal_fs_directory_exists(directory.c_str())); } - TEST(PAL_FS, pal_pal_fs_rmdir_RemovesDirectoryWithEmptySubDirectory) - { + TEST(PAL_FS, pal_pal_fs_rmdir_RemovesDirectoryWithEmptySubDirectory) { const auto working_dir = testutils::get_process_cwd(); const auto parent_dir = testutils::mkdir_random(working_dir); const auto sub_dir = testutils::mkdir(parent_dir, "subdirectory"); @@ -477,8 +421,7 @@ namespace EXPECT_FALSE(pal_fs_directory_exists(parent_dir.c_str())); } - TEST(PAL_FS, pal_pal_fs_rmdir_RemovesDirectoryWithMultipleSubDirectories) - { + TEST(PAL_FS, pal_pal_fs_rmdir_RemovesDirectoryWithMultipleSubDirectories) { const auto working_dir = testutils::get_process_cwd(); const auto parent_dir = testutils::mkdir_random(working_dir); const auto parent_dir_filename = testutils::mkfile(parent_dir, "test.txt"); @@ -498,19 +441,16 @@ namespace EXPECT_FALSE(pal_fs_directory_exists(parent_dir.c_str())); } - TEST(PAL_FS, pal_fs_rmfile_DoesNotSegFault) - { + TEST(PAL_FS, pal_fs_rmfile_DoesNotSegFault) { EXPECT_FALSE(pal_fs_rmfile(nullptr)); } - TEST(PAL_FS, pal_fs_rmfile_ThatDoesNotExist) - { + TEST(PAL_FS, pal_fs_rmfile_ThatDoesNotExist) { const auto random_filename = testutils::build_random_filename(); EXPECT_FALSE(pal_fs_rmfile(random_filename.c_str())); } - TEST(PAL_FS, pal_fs_rmfile) - { + TEST(PAL_FS, pal_fs_rmfile) { const auto random_filename = testutils::build_random_filename(); const auto working_dir = testutils::get_process_cwd(); const auto dst_filename = testutils::mkfile(working_dir, random_filename.c_str()); @@ -519,56 +459,48 @@ namespace EXPECT_FALSE(pal_fs_file_exists(dst_filename.c_str())); } - TEST(PAL_FS, pal_fs_fwrite_DoesNotSegfault) - { + TEST(PAL_FS, pal_fs_fwrite_DoesNotSegfault) { EXPECT_FALSE(pal_fs_write(nullptr, nullptr, 0)); } // - Path - TEST(PAL_PATH, pal_path_normalize_DoesNotSegfault) - { + TEST(PAL_PATH, pal_path_normalize_DoesNotSegfault) { EXPECT_FALSE(pal_path_normalize(nullptr, nullptr)); } - TEST(PAL_PATH, pal_path_get_directory_name_DoesNotSegfault) - { + TEST(PAL_PATH, pal_path_get_directory_name_DoesNotSegfault) { EXPECT_FALSE(pal_path_get_directory_name(nullptr, nullptr)); } - TEST(PAL_PATH, pal_path_get_directory_name) - { + TEST(PAL_PATH, pal_path_get_directory_name) { const auto working_dir = testutils::get_process_cwd(); const auto working_dir_name = testutils::get_directory_name(working_dir); - char* directory_name = nullptr; + char *directory_name = nullptr; ASSERT_TRUE(pal_path_get_directory_name(working_dir.c_str(), &directory_name)); ASSERT_STREQ(directory_name, working_dir_name.c_str()); } - TEST(PAL_PATH, pal_path_combine_DoesNotSegFault) - { + TEST(PAL_PATH, pal_path_combine_DoesNotSegFault) { EXPECT_FALSE(pal_path_combine(nullptr, nullptr, nullptr)); } - TEST(PAL_PATH, pal_path_get_directory_name_from_file_path_DoesNotSegFault) - { + TEST(PAL_PATH, pal_path_get_directory_name_from_file_path_DoesNotSegFault) { EXPECT_FALSE(pal_path_get_directory_name_from_file_path(nullptr, nullptr)); } - TEST(PAL_PATH, pal_path_get_directory_name_from_file_path) - { + TEST(PAL_PATH, pal_path_get_directory_name_from_file_path) { const auto working_dir = testutils::get_process_cwd(); const auto exe_real_path = testutils::get_process_real_path(); - char* full_path_dir_name = nullptr; + char *full_path_dir_name = nullptr; EXPECT_TRUE(pal_path_get_directory_name_from_file_path(exe_real_path.c_str(), &full_path_dir_name)); ASSERT_STREQ(working_dir.c_str(), full_path_dir_name); } // - String - TEST(PAL_STRING, pal_str_endswith) - { + TEST(PAL_STRING, pal_str_endswith) { EXPECT_TRUE(pal_str_endswith("test.nupkg", ".nupkg")); EXPECT_FALSE(pal_str_endswith("test.nupkg", ".nupk")); EXPECT_FALSE(pal_str_endswith(nullptr, nullptr)); @@ -576,8 +508,7 @@ namespace EXPECT_FALSE(pal_str_endswith(".nupkg", nullptr)); } - TEST(PAL_STRING, pal_str_startswith) - { + TEST(PAL_STRING, pal_str_startswith) { EXPECT_TRUE(pal_str_startswith("test.nupkg", "test")); EXPECT_FALSE(pal_str_startswith("test.nupkg", "yolo")); EXPECT_FALSE(pal_str_startswith(nullptr, ".nupkg")); @@ -585,8 +516,7 @@ namespace EXPECT_FALSE(pal_str_startswith(nullptr, nullptr)); } - TEST(PAL_STRING, pal_str_iequals) - { + TEST(PAL_STRING, pal_str_iequals) { EXPECT_TRUE(pal_str_iequals("test.nupkg", "TEST.NUPKG")); EXPECT_TRUE(pal_str_iequals("test.NUPKG", "TEST.nupkg")); EXPECT_FALSE(pal_str_iequals("test.nupkg", "TEST.nupk")); @@ -595,8 +525,7 @@ namespace EXPECT_TRUE(pal_str_iequals(nullptr, nullptr)); } - TEST(PAL_STRING, pal_str_is_null_or_whitespace) - { + TEST(PAL_STRING, pal_str_is_null_or_whitespace) { EXPECT_TRUE(pal_str_is_null_or_whitespace(nullptr)); EXPECT_TRUE(pal_str_is_null_or_whitespace("")); EXPECT_TRUE(pal_str_is_null_or_whitespace(" ")); @@ -617,4 +546,4 @@ namespace pal_semaphore_machine_wide sema3(sema_name); EXPECT_TRUE(sema2.try_create()); } -} +} \ No newline at end of file diff --git a/src/Snap.CoreRun.Pal/test/unix.cpp b/src/Snap.CoreRun.Pal/test/unix.cpp index 2bf507c6..d4908429 100644 --- a/src/Snap.CoreRun.Pal/test/unix.cpp +++ b/src/Snap.CoreRun.Pal/test/unix.cpp @@ -5,11 +5,8 @@ using testutils = corerun::support::util::test_utils; -namespace -{ - - struct path_combine_test_case - { +namespace { + struct path_combine_test_case { public: const char *path1; const char *path2; @@ -17,25 +14,20 @@ namespace path_combine_test_case() = delete; - path_combine_test_case(const char* path1, const char* path2, const char* value) : - path1(path1), path2(path2), value(value) - { - + path_combine_test_case(const char *path1, const char *path2, const char *value) : path1(path1), path2(path2), + value(value) { } }; - struct path_normalize_test_case - { + struct path_normalize_test_case { public: const char *input; const char *expected_value; path_normalize_test_case() = delete; - path_normalize_test_case(const char* input, const char* expected_value) : - input(input), expected_value(expected_value) - { - + path_normalize_test_case(const char *input, const char *expected_value) : input(input), + expected_value(expected_value) { } }; @@ -119,90 +111,78 @@ namespace path_normalize_test_case("d/./e/.././o/f/g/./h/../../.././n/././e/./i/..", "d/o/n/e") }; - TEST(PAL_GENERIC_UNIX, pal_is_linux) - { - ASSERT_TRUE(pal_is_linux()); + TEST(PAL_GENERIC_UNIX, pal_is_linux) { + ASSERT_TRUE(pal_is_linux()); } - TEST(PAL_GENERIC_UNIX, pal_is_windows) - { + TEST(PAL_GENERIC_UNIX, pal_is_windows) { ASSERT_FALSE(pal_is_windows()); } - TEST(PAL_GENERIC_UNIX, pal_is_windows_8_or_greater) - { + TEST(PAL_GENERIC_UNIX, pal_is_windows_8_or_greater) { ASSERT_FALSE(pal_is_windows_8_or_greater()); } - TEST(PAL_GENERIC_UNIX, pal_is_windows_7_or_greater) - { + TEST(PAL_GENERIC_UNIX, pal_is_windows_7_or_greater) { ASSERT_FALSE(pal_is_windows_7_or_greater()); } - TEST(PAL_GENERIC_UNIX, pal_process_exec) - { - auto exit_code = 1; + TEST(PAL_GENERIC_UNIX, pal_process_exec) { + auto exit_code = 1; const auto working_dir = testutils::get_process_cwd(); ASSERT_TRUE(pal_process_exec("ls", working_dir.c_str(), -1, nullptr, &exit_code)); ASSERT_EQ(exit_code, 0); } - TEST(PAL_ENV_UNIX, pal_env_get_variable_Reads_PWD_Variable) - { + TEST(PAL_ENV_UNIX, pal_env_get_variable_Reads_PWD_Variable) { char *environment_variable = nullptr; ASSERT_TRUE(pal_env_get("PWD", &environment_variable)); ASSERT_NE(environment_variable, nullptr); } - TEST(PAL_FS_UNIX, pal_process_get_name_ReturnsThisProcessExeName) - { + TEST(PAL_FS_UNIX, pal_process_get_name_ReturnsThisProcessExeName) { char *exe_name = nullptr; ASSERT_TRUE(pal_process_get_name(&exe_name)); ASSERT_NE(exe_name, nullptr); ASSERT_STREQ(exe_name, "corerun_tests"); } - TEST(Disable_PAL_FS_UNIX, pal_fs_get_cwd_ReturnsCurrentWorkingDirectoryForThisProcess) - { - char* working_dir = nullptr; + TEST(Disable_PAL_FS_UNIX, pal_fs_get_cwd_ReturnsCurrentWorkingDirectoryForThisProcess) { + char *working_dir = nullptr; ASSERT_TRUE(pal_fs_get_cwd(&working_dir)); ASSERT_TRUE(pal_fs_directory_exists(working_dir)); } - TEST(PAL_PATH_UNIX, pal_path_combine) - { + TEST(PAL_PATH_UNIX, pal_path_combine) { ASSERT_GT(path_combine_test_cases.size(), 0u); - for (const auto &test_case : path_combine_test_cases) - { - auto path_combined = std::make_unique(nullptr); + for (const auto &test_case: path_combine_test_cases) { + auto path_combined = std::make_unique(nullptr); const auto ASSERT_success = test_case.value == nullptr ? FALSE : TRUE; ASSERT_EQ(pal_path_combine(test_case.path1, test_case.path2, path_combined.get()), ASSERT_success); ASSERT_STREQ(*path_combined, test_case.value); } } - TEST(PAL_PATH_UNIX, pal_path_normalize) - { + TEST(PAL_PATH_UNIX, pal_path_normalize) { ASSERT_GT(path_normalize_test_cases.size(), 0u); auto test_case_index = 0; - for (const auto &test_case : path_normalize_test_cases) - { - auto path_normalized = std::make_unique(nullptr); + for (const auto &test_case: path_normalize_test_cases) { + auto path_normalized = std::make_unique(nullptr); const auto ASSERT_success = test_case.expected_value == nullptr ? FALSE : TRUE; EXPECT_EQ(pal_path_normalize(test_case.input, path_normalized.get()), ASSERT_success) - << " @Input:" << test_case.input - << " @Expected:" << test_case.expected_value - << " @Normalized:" << *path_normalized - << " @Test case index:" << std::to_string(test_case_index); + << " @Input:" << test_case.input + << " @Expected:" << test_case.expected_value + << " @Normalized:" << *path_normalized + << " @Test case index:" << std::to_string(test_case_index); EXPECT_STREQ(*path_normalized, test_case.expected_value) - << " @Input:" << test_case.input - << " @Expected:" << test_case.expected_value - << " @Normalized:" << *path_normalized - << " @Test case index:" << std::to_string(test_case_index); + << " @Input:" << test_case.input + << " @Expected:" << test_case.expected_value + << " @Normalized:" << *path_normalized + << " @Test case index:" << std::to_string(test_case_index); test_case_index++; } @@ -225,5 +205,4 @@ namespace << " @Expected:" << test_case.expected_value << " @Normalized:" << *path_normalized; }*/ - -} +} \ No newline at end of file diff --git a/src/Snap.CoreRun.Pal/test/windows.cpp b/src/Snap.CoreRun.Pal/test/windows.cpp index 0adca596..7a5fc4dd 100644 --- a/src/Snap.CoreRun.Pal/test/windows.cpp +++ b/src/Snap.CoreRun.Pal/test/windows.cpp @@ -4,42 +4,39 @@ using testutils = corerun::support::util::test_utils; -namespace -{ - struct path_combine_test_case - { +namespace { + struct path_combine_test_case { public: const char *path1; const char *path2; const char *combined; - path_combine_test_case() = delete; - path_combine_test_case(const char* path1, const char* path2, const char* combined) : - path1(path1), path2(path2), combined(combined) - { + path_combine_test_case() = delete; + path_combine_test_case(const char *path1, const char *path2, const char *combined) : path1(path1), path2(path2), + combined(combined) { } }; // https://github.com/wine-mirror/wine/blob/6a04cf4a69205ddf6827fb2a4b97862fd1947c62/dlls/shlwapi/tests/path.c std::vector path_combine_test_cases = { - /* normal paths */ - path_combine_test_case("C:\\", "a", "C:\\a"), + /* normal paths */ + path_combine_test_case("C:\\", "a", "C:\\a"), path_combine_test_case("C:\\b", "..\\a", "C:\\a"), - path_combine_test_case("C:", "a", "C:\\a"), - path_combine_test_case("C:\\", ".", "C:\\"), - path_combine_test_case("C:\\", "..", "C:\\"), - path_combine_test_case("\\a", "b", "\\a\\b"), - path_combine_test_case("c:\\", "test", "c:\\test"), - path_combine_test_case("c:\\test", "test.txt", "c:\\test\\test.txt"), + path_combine_test_case("C:", "a", "C:\\a"), + path_combine_test_case("C:\\", ".", "C:\\"), + path_combine_test_case("C:\\", "..", "C:\\"), + path_combine_test_case("\\a", "b", "\\a\\b"), + path_combine_test_case("c:\\", "test", "c:\\test"), + path_combine_test_case("c:\\test", "test.txt", "c:\\test\\test.txt"), /* normal UNC paths */ path_combine_test_case(R"(\\192.168.1.1\test)", "a", R"(\\192.168.1.1\test\a)"), path_combine_test_case(R"(\\192.168.1.1\test)", "..", "\\\\192.168.1.1"), /* NT paths */ - path_combine_test_case(R"(\\?\C:\)", "a", "C:\\a"), + path_combine_test_case(R"(\\?\C:\)", "a", "C:\\a"), path_combine_test_case(R"(\\?\C:\)", "..", "C:\\"), /* NT UNC path */ @@ -47,8 +44,7 @@ namespace path_combine_test_case(R"(\\?\UNC\192.168.1.1\test)", "..", "\\\\192.168.1.1") }; - TEST(PAL_GENERIC_WINDOWS, pal_set_icon) - { + TEST(PAL_GENERIC_WINDOWS, pal_set_icon) { const auto working_dir = testutils::get_process_cwd(); const auto src_filename = testutils::path_combine( @@ -65,15 +61,13 @@ namespace ASSERT_TRUE(pal_fs_rmfile(dst_filename.c_str())); } - TEST(PAL_GENERIC_WINDOWS, pal_is_windows) - { + TEST(PAL_GENERIC_WINDOWS, pal_is_windows) { EXPECT_TRUE(pal_is_windows()); EXPECT_FALSE(pal_is_linux()); } - TEST(PAL_GENERIC_WINDOWS, pal_process_exec) - { - const auto working_dir = std::make_unique(new char); + TEST(PAL_GENERIC_WINDOWS, pal_process_exec) { + const auto working_dir = std::make_unique(new char); EXPECT_TRUE(pal_process_get_cwd(working_dir.get())); pal_exit_code_t exit_code = 1; @@ -81,78 +75,67 @@ namespace EXPECT_EQ(exit_code, 0); } - TEST(PAL_FS_WINDOWS, pal_fs_file_exists_ReturnsFalseIfDirectory) - { - const auto working_dir = std::make_unique(new char); + TEST(PAL_FS_WINDOWS, pal_fs_file_exists_ReturnsFalseIfDirectory) { + const auto working_dir = std::make_unique(new char); EXPECT_TRUE(pal_fs_get_cwd(working_dir.get())); ASSERT_FALSE(pal_fs_file_exists(*working_dir)); } - TEST(PAL_FS_WINDOWS, pal_fs_file_exists_ReturnsTrueWhenAbsolutePath) - { - const auto exe_abs_path = std::make_unique(new char); + TEST(PAL_FS_WINDOWS, pal_fs_file_exists_ReturnsTrueWhenAbsolutePath) { + const auto exe_abs_path = std::make_unique(new char); EXPECT_TRUE(pal_process_get_real_path(exe_abs_path.get())); EXPECT_TRUE(pal_fs_file_exists(*exe_abs_path)); } - TEST(PAL_FS_WINDOWS, pal_fs_get_cwd_ReturnsCurrentWorkingDirectoryForThisProcess) - { + TEST(PAL_FS_WINDOWS, pal_fs_get_cwd_ReturnsCurrentWorkingDirectoryForThisProcess) { const auto process_working_dir = testutils::get_process_cwd(); #if defined(PAL_PLATFORM_WINDOWS) pal_utf16_string process_working_dir_utf16_str(process_working_dir); EXPECT_STRNE(process_working_dir_utf16_str.data(), nullptr); EXPECT_GT(SetCurrentDirectory(process_working_dir_utf16_str.data()), 0); #endif - char* working_dir = nullptr; + char *working_dir = nullptr; EXPECT_TRUE(pal_fs_get_cwd(&working_dir)); EXPECT_TRUE(pal_fs_directory_exists(working_dir)); delete working_dir; } - TEST(PAL_FS_WINDOWS, pal_process_get_name_ReturnsThisProcessExeName) - { - char* exe_name = nullptr; + TEST(PAL_FS_WINDOWS, pal_process_get_name_ReturnsThisProcessExeName) { + char *exe_name = nullptr; EXPECT_TRUE(pal_process_get_name(&exe_name)); ASSERT_STREQ(exe_name, "corerun_tests.exe"); } - TEST(PAL_ENV_WINDOWS, pal_env_get_Reads_PATH_Variable) - { - char* environment_variable = nullptr; + TEST(PAL_ENV_WINDOWS, pal_env_get_Reads_PATH_Variable) { + char *environment_variable = nullptr; EXPECT_TRUE(pal_env_get("PATH", &environment_variable)); EXPECT_NE(environment_variable, nullptr); } - TEST(PAL_PATH_WINDOWS, pal_path_normalize) - { + TEST(PAL_PATH_WINDOWS, pal_path_normalize) { const auto input_str = std::string("C:/test/123"); const auto expected_str = std::string("C:\\test\\123"); - char* path_normalized = nullptr; + char *path_normalized = nullptr; ASSERT_TRUE(pal_path_normalize(input_str.c_str(), &path_normalized)); ASSERT_STREQ(path_normalized, expected_str.c_str()); } - TEST(PAL_PATH_WINDOWS, pal_path_combine) - { + TEST(PAL_PATH_WINDOWS, pal_path_combine) { ASSERT_GT(path_combine_test_cases.size(), 0u); - for (const auto &test_case : path_combine_test_cases) - { - auto path_combined = std::make_unique(new char); + for (const auto &test_case: path_combine_test_cases) { + auto path_combined = std::make_unique(new char); EXPECT_TRUE(pal_path_combine(test_case.path1, test_case.path2, path_combined.get())); EXPECT_STREQ(*path_combined, test_case.combined); } } - TEST(PAL_STR_WINDOWS, pal_str_widen_DoesNotSegfault) - { + TEST(PAL_STR_WINDOWS, pal_str_widen_DoesNotSegfault) { EXPECT_EQ(pal_str_widen(nullptr), nullptr); } - TEST(PAL_STR_WINDOWS, pal_str_narrow_DoesNotSegfault) - { + TEST(PAL_STR_WINDOWS, pal_str_narrow_DoesNotSegfault) { EXPECT_EQ(pal_str_widen(nullptr), nullptr); } - -} +} \ No newline at end of file diff --git a/src/Snap.CoreRun.Tests/CMakeLists.txt b/src/Snap.CoreRun.Tests/CMakeLists.txt index 68141f99..be5f8f45 100644 --- a/src/Snap.CoreRun.Tests/CMakeLists.txt +++ b/src/Snap.CoreRun.Tests/CMakeLists.txt @@ -1,82 +1,80 @@ -cmake_minimum_required (VERSION 3.10 FATAL_ERROR) +cmake_minimum_required(VERSION 3.10 FATAL_ERROR) project(corerun_tests CXX) -set(corerun_tests_SOURCES - ${GTEST_ALL_CPP_FILENAME} - ../Vendor/nanoid_cpp/src/nanoid/crypto_random.cpp - ../Vendor/nanoid_cpp/src/nanoid/nanoid.cpp - ../Snap.CoreRun.Pal/test/anyos.cpp - ../Snap.CoreRun/test/anyos.cpp - src/main.cpp +set(corerun_tests_SOURCES + ${GTEST_ALL_CPP_FILENAME} + ../Snap.CoreRun.Pal/test/anyos.cpp + ../Snap.CoreRun/test/anyos.cpp + src/main.cpp ) list(APPEND corerun_tests_INCLUDE_DIRS_VENDOR - ${gtest_SOURCE_DIR}/include - ${gtest_SOURCE_DIR} - ../Vendor - ../Vendor/nanoid_cpp/inc - ../Vendor/json/include + ${gtest_SOURCE_DIR}/include + ${gtest_SOURCE_DIR} + ../Vendor + ../Vendor/nanoid_cpp/inc + ../Vendor/json/include ) -if(WIN32) +if (WIN32) list(APPEND corerun_tests_SOURCES - ../Snap.CoreRun.Pal/test/windows.cpp + ../Snap.CoreRun.Pal/test/windows.cpp ) list(APPEND corerun_tests_LIBS - ole32 - kernel32 - ntdll + ole32 + kernel32 + ntdll ) -elseif(UNIX) +elseif (UNIX) list(APPEND corerun_tests_SOURCES - ../Snap.CoreRun.Pal/test/unix.cpp + ../Snap.CoreRun.Pal/test/unix.cpp ) -endif() +endif () add_executable(corerun_tests ${corerun_tests_SOURCES}) - + include_directories(corerun_tests SYSTEM - ${corerun_tests_INCLUDE_DIRS_VENDOR} + ${corerun_tests_INCLUDE_DIRS_VENDOR} ) target_include_directories(corerun_tests PRIVATE - src/include - ${corerun_tests_INCLUDE_DIRS_VENDOR} + src/include + ${corerun_tests_INCLUDE_DIRS_VENDOR} ) -target_compile_definitions(corerun_tests PRIVATE - ${corerun_tests_DEFINES} -) +target_compile_definitions(corerun_tests PRIVATE + ${corerun_tests_DEFINES} +) target_link_libraries(corerun_tests PRIVATE - ${corerun_tests_LIBS} - corerun_static - gtest - gtest_main) + ${corerun_tests_LIBS} + corerun_static + gtest + gtest_main) add_custom_target(always_copy_test_dependencies ALL - COMMAND ${CMAKE_COMMAND} -E echo "Copying tests assets to directory: $" - COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/Snap.CoreRun/src/resources/CoreRun.ico" "$/test.ico" - COMMAND ${CMAKE_COMMAND} -E copy "$" "$" - COMMAND ${CMAKE_COMMAND} -E copy "$" "$" + COMMAND ${CMAKE_COMMAND} -E echo "Copying tests assets to directory: $" + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/Snap.CoreRun/src/resources/CoreRun.ico" "$/test.ico" + COMMAND ${CMAKE_COMMAND} -E copy "$" "$" + COMMAND ${CMAKE_COMMAND} -E copy "$" "$" ) add_custom_command(TARGET corerun_tests PRE_BUILD DEPENDS always_copy_test_dependencies - COMMAND ${CMAKE_COMMAND} -E echo ) + COMMAND ${CMAKE_COMMAND} -E echo) -if(WIN32) +if (WIN32) if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") add_custom_command( - TARGET corerun_tests - POST_BUILD - COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\corerun_tests.exe.manifest\" + TARGET corerun_tests + POST_BUILD + COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\corerun_tests.exe.manifest\" -inputresource:\"$\" -outputresource:\"$\" - COMMENT "Adding corerun_tests manifest" - ) - endif() -endif() + COMMENT "Adding corerun_tests manifest" + ) + endif () +endif () set_property(TARGET corerun_tests PROPERTY CXX_STANDARD 17) set_property(TARGET corerun_tests PROPERTY CXX_STANDARD_REQUIRED ON) diff --git a/src/Snap.CoreRun.Tests/src/include/tests/support/unique_id.hpp b/src/Snap.CoreRun.Tests/src/include/tests/support/unique_id.hpp new file mode 100644 index 00000000..1d293f87 --- /dev/null +++ b/src/Snap.CoreRun.Tests/src/include/tests/support/unique_id.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include +#include +#include + +namespace unique_id { + namespace detail { + // URL-safe characters similar to nanoid + constexpr const char *alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-"; + constexpr size_t alphabet_size = 64; + constexpr size_t default_size = 21; + + inline std::mt19937_64 &get_rng() { + static thread_local std::mt19937_64 rng( + static_cast( + std::chrono::high_resolution_clock::now().time_since_epoch().count() + ) + ); + return rng; + } + } + + inline std::string generate(size_t size = detail::default_size) { + std::uniform_int_distribution dist(0, detail::alphabet_size - 1); + auto &rng = detail::get_rng(); + + std::string result; + result.reserve(size); + + for (size_t i = 0; i < size; ++i) { + result += detail::alphabet[dist(rng)]; + } + + return result; + } +} + +// Compatibility namespace for existing nanoid usage +namespace nanoid { + inline std::string generate(size_t size = unique_id::detail::default_size) { + return unique_id::generate(size); + } +} \ No newline at end of file diff --git a/src/Snap.CoreRun.Tests/src/include/tests/support/utils.hpp b/src/Snap.CoreRun.Tests/src/include/tests/support/utils.hpp index 9f025be6..e94c544b 100644 --- a/src/Snap.CoreRun.Tests/src/include/tests/support/utils.hpp +++ b/src/Snap.CoreRun.Tests/src/include/tests/support/utils.hpp @@ -1,156 +1,128 @@ #pragma once -#include "pal/pal.hpp" -#include "nanoid/nanoid.h" #include +#include // for strlen +#include -namespace corerun -{ - namespace support - { - namespace util - { - class test_utils - { - public: +#include "pal/pal.hpp" +#include "tests/support/unique_id.hpp" - static bool file_copy(const std::string& src_filename, const std::string& dest_filename) - { - const auto bytes = std::make_unique(nullptr); +namespace corerun { + namespace support { + namespace util { + class test_utils { + public: + static bool file_copy(const std::string &src_filename, const std::string &dest_filename) { + const auto bytes = std::make_unique(nullptr); size_t bytes_len = 0; - if (!pal_fs_read_file(src_filename.c_str(), bytes.get(), &bytes_len)) - { + if (!pal_fs_read_file(src_filename.c_str(), bytes.get(), &bytes_len)) { return false; } - if (!pal_fs_write(dest_filename.c_str(), *bytes, bytes_len)) - { + if (!pal_fs_write(dest_filename.c_str(), *bytes, bytes_len)) { return false; } return pal_fs_chmod(dest_filename.c_str(), 0777) == TRUE; } - static std::string path_combine(const std::string &path1, const std::string &path2) - { - const auto path_combined = std::make_unique(nullptr); - if (!pal_path_combine(path1.c_str(), path2.c_str(), path_combined.get())) - { + static std::string path_combine(const std::string &path1, const std::string &path2) { + const auto path_combined = std::make_unique(nullptr); + if (!pal_path_combine(path1.c_str(), path2.c_str(), path_combined.get())) { return std::string(); } return std::string(*path_combined); } - static std::string get_process_cwd() - { - const auto working_dir = std::make_unique(nullptr); - if (!pal_process_get_cwd(working_dir.get())) - { + static std::string get_process_cwd() { + const auto working_dir = std::make_unique(nullptr); + if (!pal_process_get_cwd(working_dir.get())) { return std::string(); } return std::string(*working_dir); } - static std::string get_directory_name(const std::string& full_path) - { + static std::string get_directory_name(const std::string &full_path) { const auto directory_name_start_pos = full_path.find_last_of(PAL_DIRECTORY_SEPARATOR_C); - if (directory_name_start_pos == std::string::npos) - { + if (directory_name_start_pos == std::string::npos) { return std::string(); } return full_path.substr(directory_name_start_pos + 1); } - static std::string get_process_real_path() - { - const auto exe_filename = std::make_unique(new char); - if (!pal_process_get_real_path(exe_filename.get())) - { + static std::string get_process_real_path() { + const auto exe_filename = std::make_unique(new char); + if (!pal_process_get_real_path(exe_filename.get())) { return std::string(); } return std::string(*exe_filename); } - static std::string mkdir_random(const std::string& working_dir, const pal_mode_t mode = 0777) - { - if (mode <= 0) - { + static std::string mkdir_random(const std::string &working_dir, const pal_mode_t mode = 0777) { + if (mode <= 0) { return std::string(); } - const auto random_dir = std::make_unique(nullptr); - if(!pal_path_combine(working_dir.c_str(), nanoid::generate().c_str(), random_dir.get())) - { + const auto random_dir = std::make_unique(nullptr); + if (!pal_path_combine(working_dir.c_str(), nanoid::generate().c_str(), random_dir.get())) { return std::string(); } - if (!pal_fs_mkdir(*random_dir, mode)) - { + if (!pal_fs_mkdir(*random_dir, mode)) { return std::string(); } return std::string(*random_dir); } - static std::string mkdir(const std::string& working_dir, const char* directory_name, const pal_mode_t mode = 0777) - { - if (directory_name == nullptr) - { + static std::string mkdir(const std::string &working_dir, const char *directory_name, + const pal_mode_t mode = 0777) { + if (directory_name == nullptr) { return std::string(); } - const auto dst_directory = std::make_unique(nullptr); - if(!pal_path_combine(working_dir.c_str(), nanoid::generate().c_str(), dst_directory.get())) - { + const auto dst_directory = std::make_unique(nullptr); + if (!pal_path_combine(working_dir.c_str(), nanoid::generate().c_str(), dst_directory.get())) { return std::string(); } - if (!pal_fs_mkdir(*dst_directory, mode)) - { + if (!pal_fs_mkdir(*dst_directory, mode)) { return std::string(); } return std::string(*dst_directory); } - static std::string mkfile(const std::string& dst_directory, const char* filename) - { - if (!pal_fs_directory_exists(dst_directory.c_str()) - || filename == nullptr) - { + static std::string mkfile(const std::string &dst_directory, const char *filename) { + if (!pal_fs_directory_exists(dst_directory.c_str()) || filename == nullptr) { return std::string(); } - const auto dst_filename = std::make_unique(nullptr); - if(!pal_path_combine(dst_directory.c_str(), filename, dst_filename.get())) - { + const auto dst_filename = std::make_unique(nullptr); + if (!pal_path_combine(dst_directory.c_str(), filename, dst_filename.get())) { return std::string(); } - const auto* const text = "Hello World"; - if (!pal_fs_write(*dst_filename, text, strlen(text))) - { + const auto *const text = "Hello World"; + if (!pal_fs_write(*dst_filename, text, strlen(text))) { return std::string(); } return std::string(*dst_filename); } - static std::string build_random_str() - { + static std::string build_random_str() { return nanoid::generate(); } - static std::string build_random_filename(const std::string& ext = ".txt") - { + static std::string build_random_filename(const std::string &ext = ".txt") { return build_random_str() + ext; } - static std::string build_random_dirname() - { + static std::string build_random_dirname() { return build_random_str(); } }; - } - } -} + } // namespace util + } // namespace support +} // namespace corerun diff --git a/src/Snap.CoreRun.Tests/src/main.cpp b/src/Snap.CoreRun.Tests/src/main.cpp index 1a4ce386..b8fe3072 100644 --- a/src/Snap.CoreRun.Tests/src/main.cpp +++ b/src/Snap.CoreRun.Tests/src/main.cpp @@ -1,10 +1,9 @@ #include "gtest/gtest.h" #include "corerun.hpp" -int main(int argc, char* argv[]) -{ +int main(int argc, char *argv[]) { this_exe::plog_init(); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); -} +} \ No newline at end of file diff --git a/src/Snap.CoreRun/CMakeLists.txt b/src/Snap.CoreRun/CMakeLists.txt index cdeda2ab..e72d83eb 100644 --- a/src/Snap.CoreRun/CMakeLists.txt +++ b/src/Snap.CoreRun/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.10 FATAL_ERROR) +cmake_minimum_required(VERSION 3.10 FATAL_ERROR) project(corerun CXX) @@ -7,64 +7,64 @@ set(corerun_SOURCES src/stubexecutable.cpp src/vendor/semver/semver200_comparator.cpp src/vendor/semver/semver200_parser.cpp - ) +) include_directories(SYSTEM vendor ../Vendor - ) +) add_executable(corerun ${corerun_SOURCES} src/main.cpp - ) +) add_executable(corerun_demoapp src/main_demoapp.cpp - ) +) add_library(corerun_static ${corerun_SOURCES} - ) +) target_include_directories(corerun_demoapp SYSTEM PUBLIC ../Vendor/json/include - ) +) target_link_libraries(corerun_demoapp PUBLIC pal_static - ) +) target_include_directories(corerun_static SYSTEM PUBLIC vendor - ) +) target_include_directories(corerun_static PUBLIC src - ) +) target_link_libraries(corerun_static PUBLIC pal_static - ) +) target_link_libraries(corerun PUBLIC pal_static) -if(WIN32) +if (WIN32) if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wWinMainCRTStartup /subsystem:windows") set(CMAKE_CREATE_CONSOLE_EXE "/subsystem:windows") # Override subsystem on Windows. elseif (CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mwindows -municode -Wl,-subsystem,windows") - endif() + endif () pal_mitigate_dll_hijacking_for_targets(corerun corerun_demoapp) -elseif(UNIX) +elseif (UNIX) # For historical reasons, NuGet & MSBuild treat paths without an extension as directories. add_custom_command(TARGET corerun POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ $/corerun.bin + COMMAND ${CMAKE_COMMAND} -E copy $ $/corerun.bin ) -endif() +endif () set_property(TARGET corerun corerun_static corerun_demoapp PROPERTY CXX_STANDARD 17) set_property(TARGET corerun corerun_static corerun_demoapp PROPERTY CXX_STANDARD_REQUIRED ON) diff --git a/src/Snap.CoreRun/src/corerun.hpp b/src/Snap.CoreRun/src/corerun.hpp index 4e1d343d..64e422fc 100644 --- a/src/Snap.CoreRun/src/corerun.hpp +++ b/src/Snap.CoreRun/src/corerun.hpp @@ -12,13 +12,11 @@ #include #include -class this_exe -{ +class this_exe { public: static inline pal_mode_t default_permissions = 0777; - static void plog_init() - { + static void plog_init() { const auto filename = get_logger_relative_filename(); static plog::RollingFileAppender file_appender(filename.c_str(), 1000000, 1); @@ -28,28 +26,24 @@ class this_exe #endif plog::init(plog::Severity::verbose, &file_appender) - .addAppender(&console_appender) + .addAppender(&console_appender) #if defined(PAL_PLATFORM_WINDOWS) .addAppender(&debug_output_appender) #endif - ; + ; } - static std::string get_logger_relative_filename() - { + static std::string get_logger_relative_filename() { const auto process_name = get_process_name(); - if (process_name.empty()) - { + if (process_name.empty()) { return std::string("corerun.log"); } return std::string(process_name + ".log"); } - static std::string get_process_name() - { - char* app_name = nullptr; - if (!pal_process_get_name(&app_name)) - { + static std::string get_process_name() { + char *app_name = nullptr; + if (!pal_process_get_name(&app_name)) { return std::string(); } @@ -59,25 +53,20 @@ class this_exe return app_name_str; } - static std::string build_argv_str(const std::vector& strings, const std::string& delimiter = " ") - { + static std::string build_argv_str(const std::vector &strings, const std::string &delimiter = " ") { auto ss = std::string(); - for (auto const& string : strings) - { + for (auto const &string: strings) { ss += string + delimiter; } return ss; } - static std::string build_argv_str(const uint32_t argc, char** argv) - { - if (argv == nullptr) - { + static std::string build_argv_str(const uint32_t argc, char **argv) { + if (argv == nullptr) { return std::string(); } const std::vector arguments(argv, argv + argc); return build_argv_str(arguments); } - -}; +}; \ No newline at end of file diff --git a/src/Snap.CoreRun/src/main.cpp b/src/Snap.CoreRun/src/main.cpp index dd0f00c4..5c97355b 100644 --- a/src/Snap.CoreRun/src/main.cpp +++ b/src/Snap.CoreRun/src/main.cpp @@ -1,19 +1,13 @@ #include "main.hpp" - -// MSVS -// --> -#if defined(PAL_PLATFORM_WINDOWS) +#if defined(PAL_PLATFORM_WINDOWS) #include -// ReSharper disable all int APIENTRY wWinMain( _In_ HINSTANCE h_instance, _In_opt_ HINSTANCE h_prev_instance, - _In_ LPWSTR lp_cmd_line, - _In_ const int n_cmd_show) - // ReSharper enable all -{ + _In_ LPWSTR lp_cmd_line, + _In_ const int n_cmd_show) { this_exe::plog_init(); pal_mitigate_dll_hijacking(); @@ -21,35 +15,27 @@ int APIENTRY wWinMain( auto argc = 0; const auto argw = CommandLineToArgvW(GetCommandLineW(), &argc); - auto argv = new char*[argc]; - for (auto i = 0; i < argc; i++) - { + auto argv = new char *[argc]; + for (auto i = 0; i < argc; i++) { argv[i] = pal_utf8_string(argw[i]).dup(); } LocalFree(argw); - try - { + try { return corerun_main_impl(argc, argv, n_cmd_show); - } - catch (const std::exception& e) - { + } catch (const std::exception &e) { LOGE << "Unknown error: " << e.what(); } return 1; } #else -int main(const int argc, char *argv[]) -{ - try - { +int main(const int argc, char *argv[]) { + try { this_exe::plog_init(); return corerun_main_impl(argc, argv, -1); - } - catch (const std::exception& e) - { + } catch (const std::exception &e) { LOGE << "Unknown error: " << e.what(); } return 1; diff --git a/src/Snap.CoreRun/src/main.hpp b/src/Snap.CoreRun/src/main.hpp index 0d1a50f0..052ed5d6 100644 --- a/src/Snap.CoreRun/src/main.hpp +++ b/src/Snap.CoreRun/src/main.hpp @@ -1,35 +1,46 @@ #pragma once -#include "corerun.hpp" -#include "stubexecutable.hpp" -#include "cxxopts/include/cxxopts.hpp" -#include +// Standard library includes +#include +#include +#include +#include +// Platform-specific includes #if PAL_PLATFORM_LINUX -#include "unistd.h" // fork #include +#include // fork #endif -#include +// Third-party includes +#include +#include "cxxopts/include/cxxopts.hpp" + +// Project includes +#include "corerun.hpp" +#include "stubexecutable.hpp" static std::unique_ptr corerun_supervisor_semaphore; inline int corerun_command_supervise( - const std::string& stub_executable_full_path, - std::vector& arguments, - std::map& environment_variables, + const std::string &stub_executable_full_path, + std::vector &arguments, + std::map &environment_variables, int process_id, - const std::string& process_application_id, + const std::string &process_application_id, int cmd_show_windows); + inline void main_wait_for_pid(pal_pid_t pid); + inline void snapx_maybe_wait_for_debugger(); #if PAL_PLATFORM_LINUX void corerun_main_signal_handler(int signum) { LOGD << "Interrupt signal: " << signum; - if(corerun_supervisor_semaphore != nullptr) { - LOGD << "Supervisor semaphore released: " << (corerun_supervisor_semaphore->release() ? "true" : "false"); + if (corerun_supervisor_semaphore != nullptr) { + LOGD << "Supervisor semaphore released: " + << (corerun_supervisor_semaphore->release() ? "true" : "false"); } LOGD << "Supervisor will now exit."; @@ -41,26 +52,22 @@ inline int corerun_main_impl(int argc, char **argv, const int cmd_show_windows) #if PAL_PLATFORM_LINUX std::signal(SIGTERM, corerun_main_signal_handler); #endif - + LOGD << "Process started. " - << "Startup arguments(" << std::to_string(argc) << "): " - << this_exe::build_argv_str(argc, argv); + << "Startup arguments(" << std::to_string(argc) << "): " + << this_exe::build_argv_str(argc, argv); - const auto snapx_corerun_allow_elevated_context = [] - { - const auto value = std::make_unique(new char); + const auto snapx_corerun_allow_elevated_context = [] { + const auto value = std::make_unique(new char); pal_env_get("SNAPX_CORERUN_ALLOW_ELEVATED_CONTEXT", value.get()); const auto allow = pal_str_iequals(*value, "1") || pal_str_iequals(*value, "true"); - if(allow) - { + if (allow) { LOGW << "Allowing corerun to run in an elevated context."; } return allow; }; - if (pal_is_elevated() - && !snapx_corerun_allow_elevated_context()) - { + if (pal_is_elevated() && !snapx_corerun_allow_elevated_context()) { LOGE << "Current user account is elevated to either root / Administrator, exiting.."; return 1; } @@ -76,20 +83,16 @@ inline int corerun_main_impl(int argc, char **argv, const int cmd_show_windows) auto supervise_process_id = 0; std::string supervise_id; std::vector environment_variables_vec; - options - .add_options() - ("corerun-environment-var", - "To set a single variable, use the syntax MY_VAR=value. You can also set multiple variables by separating them with a space.", - cxxopts::value>(environment_variables_vec) - ) - ("corerun-supervise-pid", - "Supervision of target process. Wait for process pid to exit and then restart it.", - cxxopts::value(supervise_process_id) - ) - ("corerun-supervise-id", - "A unique id that identifies current application.", - cxxopts::value(supervise_id) - ); + options.add_options() + ("corerun-environment-var", + "To set a single variable, use the syntax MY_VAR=value. You can also set multiple variables by separating them with a space.", + cxxopts::value >(environment_variables_vec)) + ("corerun-supervise-pid", + "Supervision of target process. Wait for process pid to exit and then restart it.", + cxxopts::value(supervise_process_id)) + ("corerun-supervise-id", + "A unique id that identifies current application.", + cxxopts::value(supervise_id)); std::map environment_variables; @@ -97,39 +100,39 @@ inline int corerun_main_impl(int argc, char **argv, const int cmd_show_windows) options.allow_unrecognised_options(); const auto result = options.parse(argc, argv); if (result.count("corerun-environment-var")) { - const auto pairs = result["corerun-environment-var"].as>(); - for (const auto& kv : pairs) { - const auto pos = kv.find('='); - if (pos == std::string::npos) { - LOGE << "Invalid environment variable pair: " << kv << ". The pair must be in the form \"key=value\""; - return 1; + const auto pairs = result["corerun-environment-var"].as >(); + for (const auto &kv: pairs) { + const auto pos = kv.find('='); + if (pos == std::string::npos) { + LOGE << "Invalid environment variable pair: " << kv + << ". The pair must be in the form \"key=value\""; + return 1; + } + const std::string key = kv.substr(0, pos); + const std::string value = kv.substr(pos + 1); + environment_variables.emplace(key, value); } - const std::string key = kv.substr(0, pos); - const std::string value = kv.substr(pos + 1); - environment_variables.emplace(key, value); - } - - for (auto it = stub_executable_arguments.begin(); it != stub_executable_arguments.end() - 1;) { - if ((*it).find("corerun-environment-var", 0) != std::string::npos) { - stub_executable_arguments.erase(it); - if(it + 1 == stub_executable_arguments.end()) { - break; - } - it = stub_executable_arguments.erase(it, it + 1); - continue; + + for (auto it = stub_executable_arguments.begin(); it != stub_executable_arguments.end() - 1;) { + if ((*it).find("corerun-environment-var", 0) != std::string::npos) { + stub_executable_arguments.erase(it); + if (it + 1 == stub_executable_arguments.end()) { + break; + } + it = stub_executable_arguments.erase(it, it + 1); + continue; + } + ++it; } - ++it; - } } - } catch (const cxxopts::OptionException &e) { LOGE << "Error parsing startup argument: " << e.what(); } if (supervise_process_id > 0) { return corerun_command_supervise(stub_executable_full_path, stub_executable_arguments, - environment_variables, - supervise_process_id, supervise_id, cmd_show_windows); + environment_variables, + supervise_process_id, supervise_id, cmd_show_windows); } return snap::stubexecutable::run(stub_executable_arguments, @@ -137,36 +140,37 @@ inline int corerun_main_impl(int argc, char **argv, const int cmd_show_windows) } inline int corerun_command_supervise( - const std::string& stub_executable_full_path, - std::vector& arguments, - std::map& environment_variables, + const std::string &stub_executable_full_path, + std::vector &arguments, + std::map &environment_variables, const int process_id, - const std::string& process_application_id, - const int cmd_show_windows) -{ - if(!pal_process_is_running(process_id)) - { - LOGE << "Supervision of target process with id " << std::to_string(process_id) << " cancelled because the program is not running."; + const std::string &process_application_id, + const int cmd_show_windows) { + if (!pal_process_is_running(process_id)) { + LOGE << "Supervision of target process with id " << std::to_string(process_id) << + " cancelled because the program is not running."; return 1; } auto semaphore_name("corerun-" + process_application_id); if (semaphore_name.size() > PAL_MAX_PATH) { - LOGW << "Semaphore name exceeds PAL_MAX_PATH length (" << std::to_string(PAL_MAX_PATH) << "). Name: " << semaphore_name; + LOGW << "Semaphore name exceeds PAL_MAX_PATH length (" << std::to_string(PAL_MAX_PATH) << "). Name: " << + semaphore_name; return 1; } corerun_supervisor_semaphore = std::make_unique(semaphore_name); - if(!corerun_supervisor_semaphore->try_create()) { - LOGE << "Aborting supervision of target process with id " << std::to_string(process_id) << " because a supervisor is already running. Process application id: " << process_application_id; + if (!corerun_supervisor_semaphore->try_create()) { + LOGE << "Aborting supervision of target process with id " << std::to_string(process_id) << + " because a supervisor is already running. Process application id: " << process_application_id; return 1; } - const auto* const corerun_dash_dash = "--corerun-"; + const auto *const corerun_dash_dash = "--corerun-"; auto index = 0; - for (const auto &value : arguments) { + for (const auto &value: arguments) { if (pal_str_startswith(value.c_str(), corerun_dash_dash)) { arguments.erase(arguments.begin() + index); } @@ -178,15 +182,14 @@ inline int corerun_command_supervise( main_wait_for_pid(process_id); LOGD << "Process exited: " << std::to_string(process_id) << ". " - << "Semaphore released: " << corerun_supervisor_semaphore->release() << ". " - << "Startup arguments("<< std::to_string(arguments.size()) << "): " - << this_exe::build_argv_str(arguments); + << "Semaphore released: " << corerun_supervisor_semaphore->release() << ". " + << "Startup arguments(" << std::to_string(arguments.size()) << "): " + << this_exe::build_argv_str(arguments); #if defined(PAL_PLATFORM_LINUX) PAL_UNUSED(cmd_show_windows); const auto child_pid = fork(); - if (child_pid == 0) - { + if (child_pid == 0) { return snap::stubexecutable::run(arguments, environment_variables, -1); } return 0; @@ -214,4 +217,4 @@ inline void snapx_maybe_wait_for_debugger() { LOGD << "Waiting for debugger to attach..."; pal_wait_for_debugger(); LOGD << "Debugger attached."; -} +} \ No newline at end of file diff --git a/src/Snap.CoreRun/src/main_demoapp.cpp b/src/Snap.CoreRun/src/main_demoapp.cpp index d8c4411a..73382873 100644 --- a/src/Snap.CoreRun/src/main_demoapp.cpp +++ b/src/Snap.CoreRun/src/main_demoapp.cpp @@ -11,24 +11,21 @@ using json = nlohmann::json; const pal_exit_code_t unit_test_success_exit_code = 0; const pal_exit_code_t unit_test_error_exit_code = 1; -int corerun_demoapp_main_impl(const int argc, char **argv) -{ +int corerun_demoapp_main_impl(const int argc, char **argv) { this_exe::plog_init(); LOGD << "Process started. Arguments: " << this_exe::build_argv_str(argc, argv); pal_mitigate_dll_hijacking(); - char* app_name = nullptr; - if (!pal_process_get_name(&app_name)) - { + char *app_name = nullptr; + if (!pal_process_get_name(&app_name)) { LOGE << "Failed to get process name."; return unit_test_error_exit_code; } - char* this_working_dir = nullptr; - if(!pal_process_get_cwd(&this_working_dir)) - { + char *this_working_dir = nullptr; + if (!pal_process_get_cwd(&this_working_dir)) { LOGE << "Failed to get current working dir."; return unit_test_error_exit_code; } @@ -42,12 +39,11 @@ int corerun_demoapp_main_impl(const int argc, char **argv) output["working_dir"] = this_working_dir; output["exit_code"] = unit_test_success_exit_code; output["command"] = std::string(); - - for (const auto &value : arguments) - { - const auto command_expected_exit_code_value = pal_str_startswith(value.c_str(), command_expected_exit_code_str.c_str()); - if (command_expected_exit_code_value) - { + + for (const auto &value: arguments) { + const auto command_expected_exit_code_value = pal_str_startswith( + value.c_str(), command_expected_exit_code_str.c_str()); + if (command_expected_exit_code_value) { const auto version_start_pos = value.find_last_of(command_expected_exit_code_str); const auto version_str = value.substr(version_start_pos + 1); @@ -64,7 +60,7 @@ int corerun_demoapp_main_impl(const int argc, char **argv) const auto json_str = ss.str(); const auto data_len = json_str.size() + 1; - auto* data = new char[data_len]; + auto *data = new char[data_len]; #if defined(PAL_PLATFORM_WINDOWS) strcpy_s(data, data_len, json_str.c_str()); #else @@ -77,7 +73,7 @@ int corerun_demoapp_main_impl(const int argc, char **argv) const auto exit_code = output["exit_code"].get(); LOGV << "Demoapp process exited. Exit code: " << exit_code; - + return exit_code; } @@ -90,42 +86,34 @@ int APIENTRY wWinMain( _In_ HINSTANCE h_instance, _In_opt_ HINSTANCE h_prev_instance, _In_ LPWSTR lp_cmd_line, - _In_ const int n_cmd_show) - // ReSharper enable all + _In_ const int n_cmd_show) +// ReSharper enable all { auto argc = 0; const auto argw = CommandLineToArgvW(GetCommandLineW(), &argc); - auto argv = new char*[argc]; - for (auto i = 0; i < argc; i++) - { + auto argv = new char *[argc]; + for (auto i = 0; i < argc; i++) { argv[i] = pal_utf8_string(argw[i]).dup(); } LocalFree(argw); - try - { + try { return corerun_demoapp_main_impl(argc, argv); - } - catch (const std::exception& e) - { + } catch (const std::exception &e) { LOGE << "Unknown error: " << e.what(); } return 1; } #else -int main(const int argc, char *argv[]) -{ - try - { +int main(const int argc, char *argv[]) { + try { return corerun_demoapp_main_impl(argc, argv); - } - catch (const std::exception& e) - { + } catch (const std::exception &e) { LOGE << "Unknown error: " << e.what(); } return 1; } -#endif +#endif \ No newline at end of file diff --git a/src/Snap.CoreRun/src/resource.h b/src/Snap.CoreRun/src/resource.h index fce908eb..9da8ac86 100644 --- a/src/Snap.CoreRun/src/resource.h +++ b/src/Snap.CoreRun/src/resource.h @@ -42,4 +42,4 @@ #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif -#endif +#endif \ No newline at end of file diff --git a/src/Snap.CoreRun/src/stubexecutable.cpp b/src/Snap.CoreRun/src/stubexecutable.cpp index 33b5e859..6f19da8b 100644 --- a/src/Snap.CoreRun/src/stubexecutable.cpp +++ b/src/Snap.CoreRun/src/stubexecutable.cpp @@ -1,25 +1,25 @@ #include "stubexecutable.hpp" -#include "vendor/semver/semver200.h" #include #include +#include + +#include "vendor/semver/semver200.h" -int snap::stubexecutable::run(std::vector arguments, const std::map& environment_variables, const int cmd_show) -{ +int snap::stubexecutable::run(std::vector arguments, + const std::map &environment_variables, const int cmd_show) { auto exit_code = 1; std::string executable_full_path; std::string app_dir_str; const auto app_name = this_exe::get_process_name(); - if (app_name.empty()) - { + if (app_name.empty()) { LOGE << "Error: Unable to find own executable name"; return exit_code; } app_dir_str = find_current_app_dir(); - if (app_dir_str.empty()) - { + if (app_dir_str.empty()) { LOGE << "Error: Unable to find current app dir"; return exit_code; } @@ -27,10 +27,9 @@ int snap::stubexecutable::run(std::vector arguments, const std::map executable_full_path = app_dir_str + PAL_DIRECTORY_SEPARATOR_C + app_name; const auto argc = static_cast(arguments.size()); - auto* const argv = new char* [argc]; + auto *const argv = new char *[argc]; - for (auto i = 0u; i < argc; i++) - { + for (auto i = 0u; i < argc; i++) { argv[i] = _strdup(arguments[i].c_str()); } @@ -38,50 +37,45 @@ int snap::stubexecutable::run(std::vector arguments, const std::map << ". Arguments(" << std::to_string(argc) << "): " << this_exe::build_argv_str(argc, argv); - for(const auto &[name, value] : environment_variables) { - if(!pal_env_set(name.c_str(), value.c_str())) { - LOGE << "Failed to set environment variable: " << name << "=" << value; + for (const auto &[name, value]: environment_variables) { + if (!pal_env_set(name.c_str(), value.c_str())) { + LOGE << "Failed to set environment variable: " << name << "=" << value; } else { - LOGI << "Set environment variable: " << name << "=" << value; + LOGI << "Set environment variable: " << name << "=" << value; } } pal_pid_t process_pid; - if (pal_process_daemonize(executable_full_path.c_str(), app_dir_str.c_str(), static_cast(argc), argv, cmd_show, &process_pid)) - { + if (pal_process_daemonize(executable_full_path.c_str(), app_dir_str.c_str(), static_cast(argc), argv, cmd_show, + &process_pid)) { LOGV << "Process successfully started. Pid: " << process_pid; exit_code = 0; - } else - { - LOGE << "Failed to start process."; + } else { + LOGE << "Failed to start process."; } return exit_code; } -std::string snap::stubexecutable::find_current_app_dir() -{ - auto cwd = std::make_unique(nullptr); - if (!pal_process_get_cwd(cwd.get())) - { +std::string snap::stubexecutable::find_current_app_dir() { + auto cwd = std::make_unique(nullptr); + if (!pal_process_get_cwd(cwd.get())) { LOGE << "Failed to get current working directory"; return {}; } std::string app_dir(*cwd); - auto paths_out = std::make_unique(nullptr); + auto paths_out = std::make_unique(nullptr); size_t paths_out_len = 0; - if (!pal_fs_list_directories(app_dir.c_str(), nullptr, nullptr, paths_out.get(), &paths_out_len)) - { + if (!pal_fs_list_directories(app_dir.c_str(), nullptr, nullptr, paths_out.get(), &paths_out_len)) { LOGE << "Failed to list directories inside app dir: " << app_dir; return {}; } - std::vector paths(*paths_out, *paths_out + paths_out_len); + std::vector paths(*paths_out, *paths_out + paths_out_len); - if (paths.empty()) - { + if (paths.empty()) { LOGE << "Could not find any directories in: " << app_dir; return {}; } @@ -90,18 +84,15 @@ std::string snap::stubexecutable::find_current_app_dir() version::Semver200_version most_recent_semver(most_recent_semver_str); auto app_dir_found = false; - for (const auto &full_path : paths) - { - auto directory_name = std::make_unique(nullptr); - if (!pal_path_get_directory_name(full_path, directory_name.get())) - { + for (const auto &full_path: paths) { + auto directory_name = std::make_unique(nullptr); + if (!pal_path_get_directory_name(full_path, directory_name.get())) { LOGE << "Unable to get directory name for directory: " << full_path; continue; } const auto directory_name_str = std::string(*directory_name); - if (!pal_str_startswith(directory_name_str.c_str(), "app-")) - { + if (!pal_str_startswith(directory_name_str.c_str(), "app-")) { LOGV << "Skipping non-app directory: " << full_path; continue; } @@ -109,18 +100,15 @@ std::string snap::stubexecutable::find_current_app_dir() auto current_app_ver_str = std::string(directory_name_str).substr(4); // Skip 'app-' version::Semver200_version current_app_semver; - try - { + try { current_app_semver = version::Semver200_version(current_app_ver_str); - } - catch (const version::Parse_error& e) - { - LOGE << "Semver parse error! App version: " << current_app_ver_str << ". Full path: " << full_path << ". Exception message: " << e.what(); + } catch (const version::Parse_error &e) { + LOGE << "Semver parse error! App version: " << current_app_ver_str + << ". Full path: " << full_path << ". Exception message: " << e.what(); continue; } - if (current_app_semver > most_recent_semver) - { + if (current_app_semver > most_recent_semver) { most_recent_semver = current_app_semver; most_recent_semver_str = current_app_ver_str; app_dir_found = true; @@ -128,17 +116,16 @@ std::string snap::stubexecutable::find_current_app_dir() } } - if(!app_dir_found) - { + if (!app_dir_found) { return {}; } const auto app_dir_version_str = "app-" + most_recent_semver_str; - auto final_dir = std::make_unique(nullptr); - if (!pal_path_combine(app_dir.c_str(), app_dir_version_str.c_str(), final_dir.get())) - { - LOGE << "Error! Unable to build final dir. App dir: " << app_dir << ". App dir version: " << app_dir_version_str; + auto final_dir = std::make_unique(nullptr); + if (!pal_path_combine(app_dir.c_str(), app_dir_version_str.c_str(), final_dir.get())) { + LOGE << "Error! Unable to build final dir. App dir: " << app_dir + << ". App dir version: " << app_dir_version_str; return {}; } diff --git a/src/Snap.CoreRun/src/stubexecutable.hpp b/src/Snap.CoreRun/src/stubexecutable.hpp index 0d879798..f7b6dcc3 100644 --- a/src/Snap.CoreRun/src/stubexecutable.hpp +++ b/src/Snap.CoreRun/src/stubexecutable.hpp @@ -6,13 +6,13 @@ #include #include -namespace snap -{ - class stubexecutable - { +namespace snap { + class stubexecutable { public: - static int run(std::vector arguments, const std::map& environment_variables, int cmd_show); + static int run(std::vector arguments, + const std::map &environment_variables, int cmd_show); + private: static std::string find_current_app_dir(); }; -} +} \ No newline at end of file diff --git a/src/Snap.CoreRun/src/targetver.h b/src/Snap.CoreRun/src/targetver.h index 87c0086d..5b1f29ca 100644 --- a/src/Snap.CoreRun/src/targetver.h +++ b/src/Snap.CoreRun/src/targetver.h @@ -5,4 +5,4 @@ // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. -#include +#include \ No newline at end of file diff --git a/src/Snap.CoreRun/test/anyos.cpp b/src/Snap.CoreRun/test/anyos.cpp index eb7e3d65..5b781612 100644 --- a/src/Snap.CoreRun/test/anyos.cpp +++ b/src/Snap.CoreRun/test/anyos.cpp @@ -2,7 +2,7 @@ #include "main.hpp" #include "nlohmann/json.hpp" #include "vendor/semver/semver200.h" -#include "nanoid/nanoid.h" +#include "tests/support/unique_id.hpp" #include "tests/support/utils.hpp" #include @@ -16,19 +16,16 @@ using testutils = corerun::support::util::test_utils; const int demoapp_default_exit_code = 0; static std::random_device dev; -static auto rng = std::mt19937_64 { dev() }; +static auto rng = std::mt19937_64{dev()}; -static bool is_ci_test() -{ - const auto value = std::make_unique(new char); +static bool is_ci_test() { + const auto value = std::make_unique(new char); pal_env_get("SNAPX_CI_BUILD", value.get()); return pal_str_iequals(*value, "1") || pal_str_iequals(*value, "true"); } namespace { - - class corerun_app_details - { + class corerun_app_details { public: std::string working_dir; std::string version_str; @@ -36,39 +33,32 @@ namespace { std::string exe_name_absolute_path; std::string exe_name_relative_path; - corerun_app_details() : - working_dir(std::string()), - version_str(std::string()), - version(version::Semver200_version()), - exe_name_absolute_path(std::string()), - exe_name_relative_path(std::string()) - { - + corerun_app_details() : working_dir(std::string()), + version_str(std::string()), + version(version::Semver200_version()), + exe_name_absolute_path(std::string()), + exe_name_relative_path(std::string()) { } corerun_app_details(std::string working_dir, std::string exe_name_absolute_path, - std::string exe_name_relative_path, - const std::string& version, const bool version_invalid) : - working_dir(std::move(working_dir)), - version_str(version), - version(version::Semver200_version(version_invalid ? "0.0.0" : version)), - exe_name_absolute_path(std::move(exe_name_absolute_path)), - exe_name_relative_path(std::move(exe_name_relative_path)) - { - + std::string exe_name_relative_path, + const std::string &version, + const bool version_invalid) : working_dir(std::move(working_dir)), + version_str(version), + version(version::Semver200_version( + version_invalid ? "0.0.0" : version)), + exe_name_absolute_path(std::move(exe_name_absolute_path)), + exe_name_relative_path(std::move(exe_name_relative_path)) { } }; - class corerun_run_details - { + class corerun_run_details { public: std::string install_dir; corerun_run_details() = delete; - explicit corerun_run_details(std::string install_dir) : install_dir(std::move(install_dir)) - { - + explicit corerun_run_details(std::string install_dir) : install_dir(std::move(install_dir)) { } ~corerun_run_details() { @@ -76,8 +66,7 @@ namespace { } }; - class stubexecutable_run_details : corerun_run_details - { + class stubexecutable_run_details : corerun_run_details { public: std::vector stub_arguments; pal_exit_code_t stub_exit_code{}; @@ -87,22 +76,19 @@ namespace { std::string run_working_dir; std::string run_command; - explicit stubexecutable_run_details(const std::string& install_dir) : - corerun_run_details(install_dir), - stub_arguments(std::vector()), - stub_exit_code(pal_exit_code_t(-1)), - app_details(corerun_app_details()), - app_exit_code(pal_exit_code_t(-1)), - app_arguments(std::vector()), - run_working_dir(std::string()), - run_command(std::string()) - { - + explicit stubexecutable_run_details(const std::string &install_dir) : corerun_run_details(install_dir), + stub_arguments( + std::vector()), + stub_exit_code(pal_exit_code_t(-1)), + app_details(corerun_app_details()), + app_exit_code(pal_exit_code_t(-1)), + app_arguments(std::vector()), + run_working_dir(std::string()), + run_command(std::string()) { } }; - class snapx - { + class snapx { private: std::string m_unique_id; std::vector m_apps; @@ -117,78 +103,79 @@ namespace { std::string os_file_ext; private: - snapx(const std::string& app_name, const std::string& working_dir, const std::string& os_file_ext) : - m_unique_id(nanoid::generate()), - m_apps(std::vector()), - app_name(app_name), - working_dir(working_dir), - working_dir_demoapp_exe(testutils::path_combine(working_dir, "corerun_demoapp" + os_file_ext)), - working_dir_corerun_exe(testutils::path_combine(working_dir, "corerun" + os_file_ext)), - install_dir(testutils::path_combine(working_dir, m_unique_id)), - install_dir_corerun_exe(testutils::path_combine(install_dir, app_name + os_file_ext)), - os_file_ext(os_file_ext) - { + snapx(const std::string &app_name, const std::string &working_dir, + const std::string &os_file_ext) : m_unique_id(nanoid::generate()), + m_apps(std::vector()), + app_name(app_name), + working_dir(working_dir), + working_dir_demoapp_exe( + testutils::path_combine( + working_dir, "corerun_demoapp" + os_file_ext)), + working_dir_corerun_exe( + testutils::path_combine(working_dir, "corerun" + os_file_ext)), + install_dir(testutils::path_combine(working_dir, m_unique_id)), + install_dir_corerun_exe( + testutils::path_combine(install_dir, app_name + os_file_ext)), + os_file_ext(os_file_ext) { init(); } public: snapx() = delete; - snapx(const std::string& app_name, const std::string& working_dir) : - snapx(app_name, working_dir, pal_is_windows() ? ".exe" : "") - { - + snapx(const std::string &app_name, const std::string &working_dir) : snapx( + app_name, working_dir, pal_is_windows() ? ".exe" : "") { } - void install(const std::string& version, const std::string& app_dir_prefix = "app-", bool version_invalid = false) - { + void install(const std::string &version, const std::string &app_dir_prefix = "app-", + bool version_invalid = false) { const auto app_dir = testutils::path_combine(this->install_dir, app_dir_prefix + version); const auto app_dir_demoapp_exe = testutils::path_combine(app_dir, this->app_name + this->os_file_ext); - ASSERT_TRUE(pal_fs_mkdirp(app_dir.c_str(), this_exe::default_permissions)) << "Failed to create app dir: " << app_dir; - ASSERT_TRUE(file_copy(this->working_dir_demoapp_exe.c_str(), app_dir_demoapp_exe.c_str())) << "Failed copy demoapp" << this->working_dir_demoapp_exe; + ASSERT_TRUE(pal_fs_mkdirp(app_dir.c_str(), this_exe::default_permissions)) << "Failed to create app dir: " + << app_dir; + ASSERT_TRUE(file_copy(this->working_dir_demoapp_exe.c_str(), app_dir_demoapp_exe.c_str())) << + "Failed copy demoapp" << this->working_dir_demoapp_exe; this->m_apps.emplace_back(corerun_app_details(app_dir, app_dir_demoapp_exe, - this->app_name + this->os_file_ext, version, version_invalid)); + this->app_name + this->os_file_ext, version, + version_invalid)); } - static bool file_copy(const char* src_filename, const char* dest_filename) - { + static bool file_copy(const char *src_filename, const char *dest_filename) { if (src_filename == nullptr - || dest_filename == nullptr) - { + || dest_filename == nullptr) { return false; } return testutils::file_copy(std::string(src_filename), std::string(dest_filename)); } - std::unique_ptr run_stubexecutable_with_args(const std::vector& arguments) - { + std::unique_ptr run_stubexecutable_with_args( + const std::vector &arguments) { const auto argc = arguments.size(); - auto* const argv = new char*[argc] {}; + auto *const argv = new char *[argc]{}; - for (auto i = 0u; i < argc; i++) - { + for (auto i = 0u; i < argc; i++) { argv[i] = _strdup(arguments[i].c_str()); } auto run_details = std::make_unique(this->install_dir); - for (const auto &value : arguments) - { + for (const auto &value: arguments) { run_details->stub_arguments.emplace_back(value); } - if (!pal_fs_directory_exists(this->install_dir.c_str())) - { + if (!pal_fs_directory_exists(this->install_dir.c_str())) { throw std::runtime_error("Fatal error! Install directory does not exist: " + this->install_dir); } pal_exit_code_t stub_executable_exit_code = 0; - if (!pal_process_exec(this->install_dir_corerun_exe.c_str(), this->install_dir.c_str(), static_cast(argc), argv, - &stub_executable_exit_code)) - { - throw std::runtime_error("Failed to start stub executable: " + this->install_dir_corerun_exe + ". Install dir: " + this->install_dir); + if (!pal_process_exec(this->install_dir_corerun_exe.c_str(), this->install_dir.c_str(), + static_cast(argc), argv, + &stub_executable_exit_code)) { + throw std::runtime_error( + "Failed to start stub executable: " + this->install_dir_corerun_exe + ". Install dir: " + this-> + install_dir); } run_details->stub_exit_code = stub_executable_exit_code; @@ -196,22 +183,19 @@ namespace { auto attempts = 5; std::string log_output; - while(attempts-- > 0) - { + while (attempts-- > 0) { // We are not synchronizing write of logoutput between parent and child process. // This means that the child process may still be writing to the file while we are reading. log_output = try_read_log_output(); - if (!log_output.empty()) - { + if (!log_output.empty()) { break; } pal_sleep_ms(300); } - if (log_output.empty()) - { + if (log_output.empty()) { return run_details; } @@ -219,29 +203,24 @@ namespace { try { json_log_output = json::parse(log_output); - } - catch (const json::exception& ex) - { + } catch (const json::exception &ex) { LOGE << "Failed to parse json output log. What: " << ex.what() << ". Output: " << log_output; return run_details; } - run_details->app_arguments = json_log_output["arguments"].get>(); + run_details->app_arguments = json_log_output["arguments"].get >(); run_details->app_exit_code = json_log_output["exit_code"].get(); run_details->run_working_dir = json_log_output["working_dir"].get(); - run_details->run_command = json_log_output["command"].get(); - + run_details->run_command = json_log_output["command"].get(); + auto expected_command = std::string(); - if(!arguments.empty()) - { + if (!arguments.empty()) { expected_command = arguments[0]; } - for (const auto &app : this->m_apps) - { - if (expected_command == run_details->run_command - && app.working_dir == run_details->run_working_dir) - { + for (const auto &app: this->m_apps) { + if (expected_command == run_details->run_command + && app.working_dir == run_details->run_working_dir) { run_details->app_details = app; break; } @@ -251,23 +230,18 @@ namespace { } private: - - void init() const - { + void init() const { ASSERT_TRUE(pal_fs_file_exists(this->working_dir_corerun_exe.c_str())); ASSERT_TRUE(pal_fs_file_exists(this->working_dir_demoapp_exe.c_str())); ASSERT_TRUE(pal_fs_mkdirp(this->install_dir.c_str(), this_exe::default_permissions)); ASSERT_TRUE(file_copy(this->working_dir_corerun_exe.c_str(), this->install_dir_corerun_exe.c_str())); } - corerun_app_details find_current_app_details() - { + corerun_app_details find_current_app_details() { corerun_app_details most_recent_app; - for (const auto &app : this->m_apps) - { - if (app.version > most_recent_app.version) - { + for (const auto &app: this->m_apps) { + if (app.version > most_recent_app.version) { most_recent_app = app; } } @@ -275,46 +249,39 @@ namespace { return most_recent_app; } - std::string try_read_log_output() - { + std::string try_read_log_output() { const auto most_recent_app = find_current_app_details(); if (most_recent_app.working_dir.empty() - || most_recent_app.exe_name_relative_path.empty()) - { + || most_recent_app.exe_name_relative_path.empty()) { return std::string(); } const auto log_filename = most_recent_app.exe_name_relative_path + ".json"; const auto log_filename_absolute_path = testutils::path_combine(most_recent_app.working_dir, log_filename); - if (log_filename_absolute_path.empty()) - { + if (log_filename_absolute_path.empty()) { LOGE << "Log file not found: " << log_filename_absolute_path; return std::string(); } - const auto log_output = std::make_unique(new char); + const auto log_output = std::make_unique(new char); size_t log_output_len = 0; - if (!pal_fs_read_file(log_filename_absolute_path.c_str(), log_output.get(), &log_output_len) || log_output_len <= 0) - { + if (!pal_fs_read_file(log_filename_absolute_path.c_str(), log_output.get(), &log_output_len) || + log_output_len <= 0) { LOGE << "Failed to read log file: " << log_filename_absolute_path << ". Size: " << log_output_len; return std::string(); } return std::string(*log_output); } - }; - TEST(MAIN, TestsCannotRunInElevatedContext) - { + TEST(MAIN, TestsCannotRunInElevatedContext) { ASSERT_NO_THROW(pal_is_elevated()); } - - TEST(MAIN, corerun_StartsWhenThereAreZeroAppsInstalled) - { - if(is_ci_test()) - { + + TEST(MAIN, corerun_StartsWhenThereAreZeroAppsInstalled) { + if (is_ci_test()) { #if defined(PAL_PLATFORM_WINDOWS) GTEST_SKIP(); #endif @@ -335,10 +302,8 @@ namespace { ASSERT_STREQ(run_details->run_command.c_str(), ""); } - TEST(MAIN, corerun_ExcludesAppDirectoriesWithInvalidPrefix) - { - if(is_ci_test()) - { + TEST(MAIN, corerun_ExcludesAppDirectoriesWithInvalidPrefix) { + if (is_ci_test()) { #if defined(PAL_PLATFORM_WINDOWS) GTEST_SKIP(); #endif @@ -352,7 +317,7 @@ namespace { snapx.install("3.0.0", "notanapp-"); snapx.install("4.0.0"); - const auto run_details = snapx.run_stubexecutable_with_args(std::vector { + const auto run_details = snapx.run_stubexecutable_with_args(std::vector{ "--expected-version=4.0.0" }); @@ -369,16 +334,13 @@ namespace { run_details->stub_arguments[0] }; - for (auto i = 0u; i < expected_arguments.size(); i++) - { + for (auto i = 0u; i < expected_arguments.size(); i++) { ASSERT_EQ(expected_arguments[i], run_details->app_arguments[i]); } } - TEST(MAIN, corerun_ExcludesAppDirectoriesWithInvalidSemver) - { - if(is_ci_test()) - { + TEST(MAIN, corerun_ExcludesAppDirectoriesWithInvalidSemver) { + if (is_ci_test()) { #if defined(PAL_PLATFORM_WINDOWS) GTEST_SKIP(); #endif @@ -392,7 +354,7 @@ namespace { snapx.install("3.0...0", "app", true); snapx.install("4.0.0"); - const auto run_details = snapx.run_stubexecutable_with_args(std::vector { + const auto run_details = snapx.run_stubexecutable_with_args(std::vector{ "--expected-version=4.0.0" }); @@ -409,16 +371,13 @@ namespace { run_details->stub_arguments[0] }; - for (auto i = 0u; i < expected_arguments.size(); i++) - { + for (auto i = 0u; i < expected_arguments.size(); i++) { ASSERT_EQ(expected_arguments[i], run_details->app_arguments[i]); } } - TEST(MAIN, corerun_StartsInitialVersion) - { - if(is_ci_test()) - { + TEST(MAIN, corerun_StartsInitialVersion) { + if (is_ci_test()) { #if defined(PAL_PLATFORM_WINDOWS) GTEST_SKIP(); #endif @@ -429,7 +388,7 @@ namespace { snapx snapx("demoapp", working_dir); snapx.install("1.0.0"); - const auto run_details = snapx.run_stubexecutable_with_args(std::vector { + const auto run_details = snapx.run_stubexecutable_with_args(std::vector{ "--expected-version=1.0.0" }); @@ -446,16 +405,13 @@ namespace { run_details->stub_arguments[0] }; - for (auto i = 0u; i < expected_arguments.size(); i++) - { + for (auto i = 0u; i < expected_arguments.size(); i++) { ASSERT_EQ(expected_arguments[i], run_details->app_arguments[i]); } } - TEST(MAIN, corerun_StartsMostRecentVersion) - { - if(is_ci_test()) - { + TEST(MAIN, corerun_StartsMostRecentVersion) { + if (is_ci_test()) { #if defined(PAL_PLATFORM_WINDOWS) GTEST_SKIP(); #endif @@ -467,7 +423,7 @@ namespace { snapx.install("1.0.0"); snapx.install("2.0.0"); - const auto run_details = snapx.run_stubexecutable_with_args(std::vector { + const auto run_details = snapx.run_stubexecutable_with_args(std::vector{ "--expected-version=2.0.0" }); @@ -484,16 +440,13 @@ namespace { run_details->stub_arguments[0] }; - for (auto i = 0u; i < expected_arguments.size(); i++) - { + for (auto i = 0u; i < expected_arguments.size(); i++) { ASSERT_EQ(expected_arguments[i], run_details->app_arguments[i]); } } - TEST(MAIN, corerun_StartsMostRecentVersionWhenThereAreLotsOfVersionsInRandomOrderInstalled) - { - if(is_ci_test()) - { + TEST(MAIN, corerun_StartsMostRecentVersionWhenThereAreLotsOfVersionsInRandomOrderInstalled) { + if (is_ci_test()) { #if defined(PAL_PLATFORM_WINDOWS) GTEST_SKIP(); #endif @@ -507,22 +460,20 @@ namespace { std::string expected_app_version = std::string(); std::vector app_versions; - for (auto major_version = 0; major_version <= app_count; major_version++) - { + for (auto major_version = 0; major_version <= app_count; major_version++) { expected_app_version = std::to_string(major_version) + ".0.0"; app_versions.emplace_back(expected_app_version); } std::shuffle(std::begin(app_versions), std::end(app_versions), rng); - for (auto const &app_version : app_versions) - { + for (auto const &app_version: app_versions) { snapx.install(app_version); } ASSERT_EQ(expected_app_version, std::to_string(app_count) + ".0.0"); - const auto run_details = snapx.run_stubexecutable_with_args(std::vector { + const auto run_details = snapx.run_stubexecutable_with_args(std::vector{ "--expected-version=" + expected_app_version }); @@ -539,10 +490,8 @@ namespace { run_details->stub_arguments[0] }; - for (auto i = 0u; i < expected_arguments.size(); i++) - { + for (auto i = 0u; i < expected_arguments.size(); i++) { ASSERT_EQ(expected_arguments[i], run_details->app_arguments[i]); } } - -} +} \ No newline at end of file diff --git a/src/Snap/Snap.csproj b/src/Snap/Snap.csproj index 5ec5f6b1..43ceb76e 100644 --- a/src/Snap/Snap.csproj +++ b/src/Snap/Snap.csproj @@ -18,9 +18,6 @@ Snapx support library. This library should be installed into your Console/WPF/Winforms/Avalonia project. - - - diff --git a/src/Snapx.sln b/src/Snapx.sln deleted file mode 100644 index e7ee969a..00000000 --- a/src/Snapx.sln +++ /dev/null @@ -1,77 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28711.60 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{543B57A3-A18F-48A6-950B-7849A45FEC93}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snap", "Snap\Snap.csproj", "{4D87A673-63F1-4872-8BC6-A00866460FB7}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snapx", "Snapx\Snapx.csproj", "{01CE9C1B-1EFB-4469-8C2C-020B785F3465}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snap.Tests", "Snap.Tests\Snap.Tests.csproj", "{4F05300A-9D3D-4262-A4FC-40D5876B7A8C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snap.Shared.Tests", "Snap.Shared.Tests\Snap.Shared.Tests.csproj", "{17505CF3-7001-415C-B08B-86B642893717}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snapx.Tests", "Snapx.Tests\Snapx.Tests.csproj", "{EA56F532-68B6-47CE-819E-D18580ED9213}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snap.Installer", "Snap.Installer\Snap.Installer.csproj", "{26A7B91C-F729-461E-B4FF-5A7B2669D8F1}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snap.Installer.Tests", "Snap.Installer.Tests\Snap.Installer.Tests.csproj", "{BA6974AB-92F6-4C2E-82C3-05BAFC6AE80A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CB1C3918-41E6-442F-982E-38476FD7CB9C}" - ProjectSection(SolutionItems) = preProject - Directory.Build.props = Directory.Build.props - ..\docker\Dockerfile = ..\docker\Dockerfile - Directory.Packages.props = Directory.Packages.props - ..\nuget.config = ..\nuget.config - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4D87A673-63F1-4872-8BC6-A00866460FB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4D87A673-63F1-4872-8BC6-A00866460FB7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4D87A673-63F1-4872-8BC6-A00866460FB7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4D87A673-63F1-4872-8BC6-A00866460FB7}.Release|Any CPU.Build.0 = Release|Any CPU - {01CE9C1B-1EFB-4469-8C2C-020B785F3465}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {01CE9C1B-1EFB-4469-8C2C-020B785F3465}.Debug|Any CPU.Build.0 = Debug|Any CPU - {01CE9C1B-1EFB-4469-8C2C-020B785F3465}.Release|Any CPU.ActiveCfg = Release|Any CPU - {01CE9C1B-1EFB-4469-8C2C-020B785F3465}.Release|Any CPU.Build.0 = Release|Any CPU - {4F05300A-9D3D-4262-A4FC-40D5876B7A8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4F05300A-9D3D-4262-A4FC-40D5876B7A8C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4F05300A-9D3D-4262-A4FC-40D5876B7A8C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4F05300A-9D3D-4262-A4FC-40D5876B7A8C}.Release|Any CPU.Build.0 = Release|Any CPU - {17505CF3-7001-415C-B08B-86B642893717}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {17505CF3-7001-415C-B08B-86B642893717}.Debug|Any CPU.Build.0 = Debug|Any CPU - {17505CF3-7001-415C-B08B-86B642893717}.Release|Any CPU.ActiveCfg = Release|Any CPU - {17505CF3-7001-415C-B08B-86B642893717}.Release|Any CPU.Build.0 = Release|Any CPU - {EA56F532-68B6-47CE-819E-D18580ED9213}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EA56F532-68B6-47CE-819E-D18580ED9213}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EA56F532-68B6-47CE-819E-D18580ED9213}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EA56F532-68B6-47CE-819E-D18580ED9213}.Release|Any CPU.Build.0 = Release|Any CPU - {26A7B91C-F729-461E-B4FF-5A7B2669D8F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {26A7B91C-F729-461E-B4FF-5A7B2669D8F1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {26A7B91C-F729-461E-B4FF-5A7B2669D8F1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {26A7B91C-F729-461E-B4FF-5A7B2669D8F1}.Release|Any CPU.Build.0 = Release|Any CPU - {BA6974AB-92F6-4C2E-82C3-05BAFC6AE80A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BA6974AB-92F6-4C2E-82C3-05BAFC6AE80A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BA6974AB-92F6-4C2E-82C3-05BAFC6AE80A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BA6974AB-92F6-4C2E-82C3-05BAFC6AE80A}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {4F05300A-9D3D-4262-A4FC-40D5876B7A8C} = {543B57A3-A18F-48A6-950B-7849A45FEC93} - {17505CF3-7001-415C-B08B-86B642893717} = {543B57A3-A18F-48A6-950B-7849A45FEC93} - {EA56F532-68B6-47CE-819E-D18580ED9213} = {543B57A3-A18F-48A6-950B-7849A45FEC93} - {BA6974AB-92F6-4C2E-82C3-05BAFC6AE80A} = {543B57A3-A18F-48A6-950B-7849A45FEC93} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {16A54F8D-2909-4DF2-AD57-172371EB1B7D} - EndGlobalSection -EndGlobal diff --git a/src/Snapx.sln.DotSettings.user b/src/Snapx.sln.DotSettings.user deleted file mode 100644 index fb581f05..00000000 --- a/src/Snapx.sln.DotSettings.user +++ /dev/null @@ -1,5 +0,0 @@ - - <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &lt;tests&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> - <Project Location="/home/peters/github/snapx/src" Presentation="&lt;tests&gt;" /> -</SessionState> - \ No newline at end of file diff --git a/src/Snapx.slnx b/src/Snapx.slnx new file mode 100644 index 00000000..cd4b2820 --- /dev/null +++ b/src/Snapx.slnx @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/Vendor/bsdiff b/src/Vendor/bsdiff index 6ba6b5d1..24ffbb4c 160000 --- a/src/Vendor/bsdiff +++ b/src/Vendor/bsdiff @@ -1 +1 @@ -Subproject commit 6ba6b5d159a9941d2baad9a4e604699874927d03 +Subproject commit 24ffbb4c1f8fe67bb69e3e906dc5b7f157f15fd9 diff --git a/src/Vendor/nanoid_cpp b/src/Vendor/nanoid_cpp deleted file mode 160000 index 404a0c20..00000000 --- a/src/Vendor/nanoid_cpp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 404a0c208e95e38fb2951208dc0b40afed2a7488 From 8e0bbcfd7fbe20774befc71b7ce2bbe0c0aa707c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 19 Sep 2025 10:12:12 +0000 Subject: [PATCH 5/5] Fix code review feedback - file-scoped namespaces, restore .NET 10.0, add macOS GitHub Actions Co-authored-by: peters <869+peters@users.noreply.github.com> --- .github/workflows/dotnetcore.yml | 77 ++++++++++++++++++- .../Snap.Installer.Tests.csproj | 2 +- src/Snap.Installer/Snap.Installer.csproj | 4 +- .../Snap.Shared.Tests.csproj | 2 +- .../AnyOS/MacOS/SnapOsMacOSTests.cs | 7 +- .../MacOS/SnapOsSpecialFoldersMacOSTests.cs | 7 +- src/Snapx.Tests/Snapx.Tests.csproj | 2 +- src/Snapx/Snapx.csproj | 2 +- 8 files changed, 88 insertions(+), 15 deletions(-) diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index d9b6ddeb..5cbac806 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -213,11 +213,86 @@ jobs: name: ${{ matrix.os }}-${{ matrix.rid }}-${{ matrix.configuration }} path: ${{ github.workspace }}/artifacts/**/* + macos: + runs-on: ${{ matrix.os }} + name: Bootstrap ${{ matrix.rid }}-${{ matrix.configuration }} + needs: [setup] + strategy: + matrix: + configuration: [Debug, Release] + rid: [osx-x64, osx-arm64] + os: [macos-latest] + env: + SNAPX_VERSION: ${{ needs.setup.outputs.SNAPX_VERSION }} + SNAPX_DOTNET_FRAMEWORK_VERSION: ${{ needs.setup.outputs.SNAPX_DOTNET_FRAMEWORK_VERSION }} + DOTNET_NET100_VERSION: ${{ needs.setup.outputs.DOTNET_NET100_VERSION }} + DOTNET_NET90_VERSION: ${{ needs.setup.outputs.DOTNET_NET90_VERSION }} + DOTNET_NET80_VERSION: ${{ needs.setup.outputs.DOTNET_NET80_VERSION }} + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + lfs: true + submodules: true + + - name: Install .NET 8.0 + uses: actions/setup-dotnet@v4.2.0 + with: + dotnet-version: ${{ env.DOTNET_NET80_VERSION }} + + - name: Install .NET 9.0 + uses: actions/setup-dotnet@v4.2.0 + with: + dotnet-version: ${{ env.DOTNET_NET90_VERSION }} + + - name: Install .NET 10.0 + uses: actions/setup-dotnet@v4.2.0 + with: + dotnet-version: ${{ env.DOTNET_NET100_VERSION }} + + - name: Bootstrap ${{ matrix.rid }}-${{ matrix.configuration }} + shell: pwsh + run: ./build.ps1 Bootstrap-Unix -Version ${{ env.SNAPX_VERSION }} -Configuration ${{ matrix.configuration }} -CIBuild -NetCoreAppVersion ${{ env.SNAPX_DOTNET_FRAMEWORK_VERSION }} -Rid ${{ matrix.rid }} + + - name: Test native + shell: pwsh + run: ./build.ps1 Run-Native-UnitTests -Version ${{ env.SNAPX_VERSION }} -Configuration ${{ matrix.configuration }} -CIBuild -NetCoreAppVersion ${{ env.SNAPX_DOTNET_FRAMEWORK_VERSION }} -Rid ${{ matrix.rid }} + + - name: Test .NET + shell: pwsh + run: ./build.ps1 Run-Dotnet-UnitTests -Version ${{ env.SNAPX_VERSION }} -Configuration ${{ matrix.configuration }} -CIBuild -NetCoreAppVersion ${{ env.SNAPX_DOTNET_FRAMEWORK_VERSION }} -Rid ${{ matrix.rid }} + + - name: Collect artifacts + env: + SNAPX_MACOS_SETUP_ZIP_REL_DIR: build/dotnet/${{ matrix.rid }}/Snap.Installer/${{ env.SNAPX_DOTNET_FRAMEWORK_VERSION }}/${{ matrix.configuration }}/publish + SNAPX_MACOS_CORERUN_REL_DIR: build/native/Unix/${{ matrix.rid }}/${{ matrix.configuration }}/Snap.CoreRun + SNAPX_MACOS_PAL_REL_DIR: build/native/Unix/${{ matrix.rid }}/${{ matrix.configuration }}/Snap.CoreRun.Pal + SNAPX_MACOS_BSDIFF_REL_DIR: build/native/Unix/${{ matrix.rid }}/${{ matrix.configuration }}/Snap.Bsdiff + run: | + mkdir -p ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_SETUP_ZIP_REL_DIR }} + cp ${{ github.workspace }}/${{ env.SNAPX_MACOS_SETUP_ZIP_REL_DIR }}/Setup-${{ matrix.rid }}.zip ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_SETUP_ZIP_REL_DIR }}/Setup-${{ matrix.rid }}.zip + + mkdir -p ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_CORERUN_REL_DIR }} + cp ${{ github.workspace }}/${{ env.SNAPX_MACOS_CORERUN_REL_DIR }}/corerun ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_CORERUN_REL_DIR }}/corerun.bin + + mkdir -p ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_PAL_REL_DIR }} + cp ${{ github.workspace }}/${{ env.SNAPX_MACOS_PAL_REL_DIR }}/libpal.dylib ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_PAL_REL_DIR }}/libpal.dylib + + mkdir -p ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_BSDIFF_REL_DIR }} + cp ${{ github.workspace }}/${{ env.SNAPX_MACOS_BSDIFF_REL_DIR }}/libsnap_bsdiff.dylib ${{ github.workspace }}/artifacts/${{ env.SNAPX_MACOS_BSDIFF_REL_DIR }}/libsnap_bsdiff.dylib + + - name: Upload artifacts + if: success() + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.os }}-${{ matrix.rid }}-${{ matrix.configuration }} + path: ${{ github.workspace }}/artifacts/**/* + publish: if: success() runs-on: ubuntu-latest name: Nupkg - needs: [setup, windows, linux] # todo: enable me when github actions supports arm64: test-linux-arm64 + needs: [setup, windows, linux, macos] # todo: enable me when github actions supports arm64: test-linux-arm64 env: SNAPX_VERSION: ${{ needs.setup.outputs.SNAPX_VERSION }} DOTNET_NET100_VERSION: ${{ needs.setup.outputs.DOTNET_NET100_VERSION }} diff --git a/src/Snap.Installer.Tests/Snap.Installer.Tests.csproj b/src/Snap.Installer.Tests/Snap.Installer.Tests.csproj index c3f95419..14ea191a 100644 --- a/src/Snap.Installer.Tests/Snap.Installer.Tests.csproj +++ b/src/Snap.Installer.Tests/Snap.Installer.Tests.csproj @@ -5,7 +5,7 @@ false true - net9.0 + net10.0 diff --git a/src/Snap.Installer/Snap.Installer.csproj b/src/Snap.Installer/Snap.Installer.csproj index 8b1d5cdb..0e1b4f32 100644 --- a/src/Snap.Installer/Snap.Installer.csproj +++ b/src/Snap.Installer/Snap.Installer.csproj @@ -7,7 +7,7 @@ Exe Snap.Installer Snap.Installer - net9.0 + net10.0 false false @@ -19,7 +19,7 @@ true - + $(NuGetPackageRoot)avalonia\$(AvaloniaVersion)\build\Avalonia.Build.Tasks.dll true diff --git a/src/Snap.Shared.Tests/Snap.Shared.Tests.csproj b/src/Snap.Shared.Tests/Snap.Shared.Tests.csproj index 3c1e630b..6e0bdf22 100644 --- a/src/Snap.Shared.Tests/Snap.Shared.Tests.csproj +++ b/src/Snap.Shared.Tests/Snap.Shared.Tests.csproj @@ -5,7 +5,7 @@ false false - net8.0;net9.0 + net8.0;net9.0;net10.0 diff --git a/src/Snap.Tests/AnyOS/MacOS/SnapOsMacOSTests.cs b/src/Snap.Tests/AnyOS/MacOS/SnapOsMacOSTests.cs index 9b6b4bd5..77f1e2a8 100644 --- a/src/Snap.Tests/AnyOS/MacOS/SnapOsMacOSTests.cs +++ b/src/Snap.Tests/AnyOS/MacOS/SnapOsMacOSTests.cs @@ -5,10 +5,10 @@ using Snap.Shared.Tests; using Xunit; -namespace Snap.Tests.AnyOS.MacOS +namespace Snap.Tests.AnyOS.MacOS; + +public class SnapOsMacOSTests : IClassFixture { - public class SnapOsMacOSTests : IClassFixture - { readonly BaseFixture _baseFixture; readonly ISnapFilesystem _snapFilesystem; readonly ISnapOs _snapOs; @@ -74,5 +74,4 @@ public void TestExitSignalHandler() Assert.NotNull(exitSignalHandler); } } -} #endif \ No newline at end of file diff --git a/src/Snap.Tests/AnyOS/MacOS/SnapOsSpecialFoldersMacOSTests.cs b/src/Snap.Tests/AnyOS/MacOS/SnapOsSpecialFoldersMacOSTests.cs index 6a8afb04..6a945697 100644 --- a/src/Snap.Tests/AnyOS/MacOS/SnapOsSpecialFoldersMacOSTests.cs +++ b/src/Snap.Tests/AnyOS/MacOS/SnapOsSpecialFoldersMacOSTests.cs @@ -3,10 +3,10 @@ using Snap.Shared.Tests; using Xunit; -namespace Snap.Tests.AnyOS.MacOS +namespace Snap.Tests.AnyOS.MacOS; + +public class SnapOsSpecialFoldersMacOSTests : IClassFixture { - public class SnapOsSpecialFoldersMacOSTests : IClassFixture - { readonly BaseFixture _baseFixture; public SnapOsSpecialFoldersMacOSTests(BaseFixture baseFixture) @@ -44,5 +44,4 @@ public void TestAnyOsReturnsMacOSOnMacOS() } } } -} #endif \ No newline at end of file diff --git a/src/Snapx.Tests/Snapx.Tests.csproj b/src/Snapx.Tests/Snapx.Tests.csproj index 0ea4b0f8..252f33b8 100644 --- a/src/Snapx.Tests/Snapx.Tests.csproj +++ b/src/Snapx.Tests/Snapx.Tests.csproj @@ -5,7 +5,7 @@ false true - net9.0 + net10.0 diff --git a/src/Snapx/Snapx.csproj b/src/Snapx/Snapx.csproj index c32b01b0..978408ed 100644 --- a/src/Snapx/Snapx.csproj +++ b/src/Snapx/Snapx.csproj @@ -11,7 +11,7 @@ true snapx true - net9.0 + net10.0 true false tools/$(TargetFramework)/any