aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-08-28 14:40:03 +0200
committerDan Engelbrecht <[email protected]>2025-01-08 10:01:23 +0100
commit54ffc9b9ad7d3d8d32e4de00980d66d4a31f3c09 (patch)
tree457c7c404bdbe7486e37bd8c699ed5716c7513e0 /src
parentclang format (diff)
downloadzen-54ffc9b9ad7d3d8d32e4de00980d66d4a31f3c09.tar.xz
zen-54ffc9b9ad7d3d8d32e4de00980d66d4a31f3c09.zip
Add ServiceSpec struct
Diffstat (limited to 'src')
-rw-r--r--src/zen/cmds/service_cmd.cpp26
-rw-r--r--src/zenutil/include/zenutil/service.h30
-rw-r--r--src/zenutil/service.cpp74
3 files changed, 79 insertions, 51 deletions
diff --git a/src/zen/cmds/service_cmd.cpp b/src/zen/cmds/service_cmd.cpp
index a93bac37c..51b41f2a0 100644
--- a/src/zen/cmds/service_cmd.cpp
+++ b/src/zen/cmds/service_cmd.cpp
@@ -211,15 +211,17 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
}
ZEN_CONSOLE(
"Service '{}':\n"
- " Status: {}\n"
- " Executable: '{}'\n"
- " Display Name: '{}'\n"
- " Description: '{}'",
+ " Status: {}\n"
+ " Executable: {}\n"
+ " CommandLineOptions: {}\n"
+ " Display Name: {}\n"
+ " Description: {}",
m_ServiceName,
ToString(Info.Status),
- Info.ExecutablePath,
- Info.DisplayName,
- Info.Description);
+ Info.Spec.ExecutablePath,
+ Info.Spec.CommandLineOptions,
+ Info.Spec.DisplayName,
+ Info.Spec.Description);
}
if (SubOption == &m_InstallOptions)
@@ -238,11 +240,11 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
}
m_ServerExecutable = std::filesystem::absolute(m_ServerExecutable);
- std::error_code Ec = InstallService(m_ServerExecutable,
- GlobalOptions.PassthroughCommandLine,
- m_ServiceName,
- m_ServiceDisplayName,
- m_ServiceDescription);
+ std::error_code Ec = InstallService(m_ServiceName,
+ ServiceSpec{.ExecutablePath = m_ServerExecutable,
+ .CommandLineOptions = GlobalOptions.PassthroughCommandLine,
+ .DisplayName = m_ServiceDisplayName,
+ .Description = m_ServiceDescription});
if (Ec)
{
ZEN_CONSOLE("Failed to install service '{}' using '{}' . Reason: '{}'", m_ServiceName, m_ServerExecutable, Ec.message());
diff --git a/src/zenutil/include/zenutil/service.h b/src/zenutil/include/zenutil/service.h
index 79be16052..cd769b67b 100644
--- a/src/zenutil/include/zenutil/service.h
+++ b/src/zenutil/include/zenutil/service.h
@@ -5,6 +5,15 @@
#include <filesystem>
namespace zen {
+
+struct ServiceSpec
+{
+ std::filesystem::path ExecutablePath;
+ std::string CommandLineOptions;
+ std::string DisplayName;
+ std::string Description;
+};
+
enum class ServiceStatus
{
NotInstalled,
@@ -17,22 +26,17 @@ enum class ServiceStatus
Resuming
};
-std::string_view ToString(ServiceStatus Status);
-
-std::error_code InstallService(const std::filesystem::path& ExecutablePath,
- std::string_view CommandLineOptions,
- std::string_view ServiceName,
- std::string_view ServiceDisplayName,
- std::string_view ServiceDescription);
-std::error_code UninstallService(std::string_view ServiceName);
struct ServiceInfo
{
- ServiceStatus Status;
- std::filesystem::path ExecutablePath;
- std::string DisplayName;
- std::string Description;
+ ServiceStatus Status;
+ ServiceSpec Spec;
};
-std::error_code QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutStatus);
+
+std::string_view ToString(ServiceStatus Status);
+
+std::error_code InstallService(std::string_view ServiceName, const ServiceSpec& Spec);
+std::error_code UninstallService(std::string_view ServiceName);
+std::error_code QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo);
std::error_code StartService(std::string_view ServiceName);
std::error_code StopService(std::string_view ServiceName);
} // namespace zen
diff --git a/src/zenutil/service.cpp b/src/zenutil/service.cpp
index 637974c13..870a47df5 100644
--- a/src/zenutil/service.cpp
+++ b/src/zenutil/service.cpp
@@ -219,11 +219,7 @@ ToString(ServiceStatus Status)
#if ZEN_PLATFORM_WINDOWS
std::error_code
-InstallService(const std::filesystem::path& ExecutablePath,
- std::string_view CommandLineOptions,
- std::string_view ServiceName,
- std::string_view ServiceDisplayName,
- std::string_view ServiceDescription)
+InstallService(std::string_view ServiceName, const ServiceSpec& Spec)
{
// Get a handle to the SCM database.
@@ -244,14 +240,14 @@ InstallService(const std::filesystem::path& ExecutablePath,
Utf8ToWide(ServiceName, Name);
ExtendableWideStringBuilder<128> DisplayName;
- Utf8ToWide(ServiceDisplayName, DisplayName);
+ Utf8ToWide(Spec.DisplayName, DisplayName);
ExtendableWideStringBuilder<128> Path;
- Path.Append(ExecutablePath.c_str());
- if (!CommandLineOptions.empty())
+ Path.Append(Spec.ExecutablePath.c_str());
+ if (!Spec.CommandLineOptions.empty())
{
Path.AppendAscii(" ");
- Utf8ToWide(CommandLineOptions, Path);
+ Utf8ToWide(Spec.CommandLineOptions, Path);
}
SC_HANDLE schService = CreateService(schSCManager, // SCM database
@@ -273,10 +269,10 @@ InstallService(const std::filesystem::path& ExecutablePath,
return MakeErrorCodeFromLastError();
}
- if (!ServiceDescription.empty())
+ if (!Spec.Description.empty())
{
ExtendableWideStringBuilder<128> DescriptionBuilder;
- Utf8ToWide(ServiceDescription, DescriptionBuilder);
+ Utf8ToWide(Spec.Description, DescriptionBuilder);
SERVICE_DESCRIPTION Description;
Description.lpDescription = const_cast<wchar_t*>(DescriptionBuilder.c_str());
@@ -380,8 +376,38 @@ QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo)
return MakeErrorCodeFromLastError();
}
- OutInfo.ExecutablePath = std::filesystem::path(ServiceConfig->lpBinaryPathName);
- OutInfo.DisplayName = WideToUtf8(ServiceConfig->lpDisplayName);
+ std::wstring BinaryWithArguments(ServiceConfig->lpBinaryPathName);
+ if (BinaryWithArguments.size())
+ {
+ if (BinaryWithArguments[0] == '"')
+ {
+ std::wstring::size_type ExecutableEnd = BinaryWithArguments.find('"', 1);
+ if (ExecutableEnd == std::wstring::npos)
+ {
+ OutInfo.Spec.ExecutablePath = BinaryWithArguments;
+ }
+ else
+ {
+ OutInfo.Spec.ExecutablePath = BinaryWithArguments.substr(0, ExecutableEnd + 1);
+ OutInfo.Spec.CommandLineOptions =
+ WideToUtf8(BinaryWithArguments.substr(ExecutableEnd + 1 + BinaryWithArguments[ExecutableEnd + 1] == ' ' ? 1 : 0));
+ }
+ }
+ else
+ {
+ std::wstring::size_type ExecutableEnd = BinaryWithArguments.find(' ', 1);
+ if (ExecutableEnd == std::wstring::npos)
+ {
+ OutInfo.Spec.ExecutablePath = BinaryWithArguments;
+ }
+ else
+ {
+ OutInfo.Spec.ExecutablePath = BinaryWithArguments.substr(0, ExecutableEnd);
+ OutInfo.Spec.CommandLineOptions = WideToUtf8(BinaryWithArguments.substr(ExecutableEnd + 1));
+ }
+ }
+ }
+ OutInfo.Spec.DisplayName = WideToUtf8(ServiceConfig->lpDisplayName);
SERVICE_STATUS ServiceStatus;
if (!::QueryServiceStatus(schService, &ServiceStatus))
@@ -435,7 +461,7 @@ QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo)
SERVICE_DESCRIPTION* Description = (SERVICE_DESCRIPTION*)Buffer.data();
if (Description->lpDescription != NULL)
{
- OutInfo.Description = WideToUtf8(std::wstring(Description->lpDescription));
+ OutInfo.Spec.Description = WideToUtf8(std::wstring(Description->lpDescription));
}
return {};
@@ -522,20 +548,16 @@ StopService(std::string_view ServiceName)
}
#else
std::error_code
-InstallService(const std::filesystem::path& ExecutablePath,
- std::string_view CommandLineOptions,
- std::string_view ServiceName,
- std::string_view ServiceDisplayName,
- std::string_view ServiceDescription)
+InstallService(std::string_view ServiceName, const ServiceSpec& Spec)
{
- std::filesystem::path SymLink = std::filesystem::path("/usr/local/libexec") / ExecutablePath.filename();
- ZEN_INFO("Attempting synlink from {} to {}", ExecutablePath.string(), SymLink.string());
- if (symlink(ExecutablePath.c_str(), SymLink.c_str()) == -1)
+ std::filesystem::path SymLink = std::filesystem::path("/usr/local/libexec") / Spec.ExecutablePath.filename();
+ ZEN_INFO("Attempting symlink from {} to {}", Spec.ExecutablePath.string(), SymLink.string());
+ if (symlink(Spec.ExecutablePath.c_str(), SymLink.c_str()) == -1)
{
return MakeErrorCodeFromLastError();
}
- std::string DaemonName = fmt::format("com.epicgames.unreal.{}", ServiceName);
- std::string PList = BuildPlist(ExecutablePath, CommandLineOptions, DaemonName, ServiceDisplayName, ServiceDescription, true);
+ std::string DaemonName = fmt::format("com.epicgames.unreal.{}", ServiceName);
+ std::string PList = BuildPlist(Spec.ExecutablePath, Spec.CommandLineOptions, DaemonName, Spec.DisplayName, Spec.Description, true);
std::filesystem::path PListPath = std::filesystem::path("/Library/LaunchDaemons") / (DaemonName + ".plist");
ZEN_INFO("Writing launchd plist to {}", PListPath.string());
zen::WriteFile(PListPath, IoBuffer(IoBuffer::Wrap, PList.data(), PList.size()));
@@ -556,9 +578,9 @@ UninstallService(std::string_view ServiceName)
}
std::error_code
-QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutStatus)
+QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo)
{
- ZEN_UNUSED(ServiceName, OutStatus);
+ ZEN_UNUSED(ServiceName, OutInfo);
ZEN_NOT_IMPLEMENTED("QueryInstalledService");
return {};
}