aboutsummaryrefslogtreecommitdiff
path: root/src/zenutil/service.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-09-18 10:43:26 +0200
committerDan Engelbrecht <[email protected]>2024-09-18 10:43:36 +0200
commit368fb049a4e66b8a6dc61938558d0865e8f88c66 (patch)
tree331ccab91c11be43341228ffcadb0912ce36e559 /src/zenutil/service.cpp
parentAdd ServiceSpec struct (diff)
downloadzen-368fb049a4e66b8a6dc61938558d0865e8f88c66.tar.xz
zen-368fb049a4e66b8a6dc61938558d0865e8f88c66.zip
wip
Diffstat (limited to 'src/zenutil/service.cpp')
-rw-r--r--src/zenutil/service.cpp142
1 files changed, 108 insertions, 34 deletions
diff --git a/src/zenutil/service.cpp b/src/zenutil/service.cpp
index 870a47df5..1637b9394 100644
--- a/src/zenutil/service.cpp
+++ b/src/zenutil/service.cpp
@@ -129,9 +129,10 @@ namespace {
}
}
- std::string BuildPlist(const std::filesystem::path& ExecutablePath,
+ std::string BuildPlist(std::string_view ServiceName,
+ const std::filesystem::path& ExecutablePath,
std::string_view CommandLineOptions,
- std::string_view ServiceName,
+ std::string_view DaemonName,
std::string_view /*ServiceDisplayName*/,
std::string_view /*ServiceDescription*/,
bool Debug)
@@ -140,7 +141,7 @@ namespace {
ExtendableStringBuilder<256> ProgramArguments;
for (const std::string_view Argument : Arguments)
{
- ProgramArguments.Append(" <string>");
+ ProgramArguments.Append(" <string>");
AppendEscaped(Argument, ProgramArguments);
ProgramArguments.Append("</string>\n");
}
@@ -149,27 +150,38 @@ namespace {
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">\n"
- " <dict>\n"
- " <key>Label</key>\n"
- " <string>{}</string>\n" // ServiceName
- " <key>ProgramArguments</key>\n"
- " <array>\n"
- " <string>{}</string>\n" // Program name
+ "<dict>\n"
+ " <key>Label</key>\n"
+ " <string>{}</string>\n" // DaemonName
+ " \n"
+ " <key>ProgramArguments</key>\n"
+ " <array>\n"
+ " <string>{}</string>\n" // Program name
"{}" // "<string>arg</string>\n" * number of arguments
- " </array>\n"
- " <key>KeepAlive</key>\n"
- " <true/>\n"
- " <key>StandardOutPath</key>\n"
- " <string>/var/log/myjob.log</string>\n"
- " <key>StandardErrorPath</key>\n"
- " <string>/var/log/myjob.log</string>\n"
- " <key>Debug</key>\n"
- " <{}/>\n"
- " </dict>\n"
+ " </array>\n"
+ " \n"
+ " <key>RunAtLoad</key>\n"
+ " <true/>\n"
+ " \n"
+// " <key>KeepAlive</key>\n"
+// " <true/>\n"
+// " \n"
+ " <key>StandardOutPath</key>\n"
+ " <string>/var/log/{}.log</string>\n"
+ " \n"
+ " <key>StandardErrorPath</key>\n"
+ " <string>/var/log/{}.err.log</string>\n"
+ " \n"
+ " <key>Debug</key>\n"
+ " <{}/>\n"
+ " \n"
+ "</dict>\n"
"</plist>\n",
- ServiceName,
- ExecutablePath.filename().string(),
+ DaemonName,
+ ExecutablePath.string(),
ProgramArguments.ToView(),
+ ServiceName,
+ ServiceName,
Debug ? "true"sv : "false"sv);
// "<key>Sockets</key>"
@@ -547,25 +559,73 @@ StopService(std::string_view ServiceName)
return {};
}
#else
+
+#if 0
+static int CopyFile(std::filesystem::path source, std::filesystem::path dest)
+{
+
+ int childExitStatus;
+ pid_t pid;
+ int status;
+
+ pid = fork();
+
+ if (pid == 0) { /* child */
+ execl("/bin/cp", "/bin/cp", source.string().c_str(), dest.string().c_str(), (char *)0);
+ return 0;
+ }
+ else if (pid < 0) {
+ return -1;
+ }
+ else {
+ /* parent - wait for child - this has all error handling, you
+ * could just call wait() as long as you are only expecting to
+ * have one child process at a time.
+ */
+ pid_t ws = waitpid( pid, &childExitStatus, WNOHANG);
+ if (ws == -1)
+ {
+ return -1;
+ }
+
+ if( WIFEXITED(childExitStatus)) /* exit code in childExitStatus */
+ {
+ status = WEXITSTATUS(childExitStatus); /* zero is normal exit */
+ return status;
+ }
+ else if (WIFSIGNALED(childExitStatus)) /* killed */
+ {
+ return -1;
+ }
+ else if (WIFSTOPPED(childExitStatus)) /* stopped */
+ {
+ return -1;
+ }
+ return -1;
+ }
+}
+#endif
+
std::error_code
InstallService(std::string_view ServiceName, const ServiceSpec& Spec)
{
- 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::filesystem::path ServicePath = std::filesystem::path("/usr/local/libexec") / ServiceName;
+// ZEN_INFO("Attempting to copy service from {} to {}", Spec.ExecutablePath.string(), ServicePath.string());
+// if (false && CopyFile(Spec.ExecutablePath, ServicePath) == -1)
+//// if (symlink(Spec.ExecutablePath.c_str(), ServicePath.c_str()) == -1)
+// {
+// return MakeErrorCodeFromLastError();
+// }
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");
+ std::string PList = BuildPlist(ServiceName, Spec.ExecutablePath, Spec.CommandLineOptions, DaemonName, Spec.DisplayName, Spec.Description, true);
+ std::filesystem::path PListPath = std::filesystem::path("/Users/dan.engelbrecht/Library/LaunchAgents") / (DaemonName + ".plist");
ZEN_INFO("Writing launchd plist to {}", PListPath.string());
zen::WriteFile(PListPath, IoBuffer(IoBuffer::Wrap, PList.data(), PList.size()));
ZEN_INFO("Changing permissions to 0555 for {}", PListPath.string());
- if (chmod(PListPath.c_str(), 0555) == -1)
- {
- return MakeErrorCodeFromLastError();
- }
+// if (chmod(PListPath.string().c_str(), 0555) == -1)
+// {
+// return MakeErrorCodeFromLastError();
+// }
return {};
}
@@ -573,7 +633,21 @@ std::error_code
UninstallService(std::string_view ServiceName)
{
ZEN_UNUSED(ServiceName);
- ZEN_NOT_IMPLEMENTED("UninstallService");
+
+ std::filesystem::path ServicePath = std::filesystem::path("/usr/local/libexec") / ServiceName;
+ ZEN_INFO("Attempting to remove service from {}", ServicePath.string());
+ if (unlink(ServicePath.string().c_str()) == -1)
+ {
+ return MakeErrorCodeFromLastError();;
+ }
+ std::string DaemonName = fmt::format("com.epicgames.unreal.{}", ServiceName);
+ std::filesystem::path PListPath = std::filesystem::path("/Library/LaunchDaemons") / (DaemonName + ".plist");
+ ZEN_INFO("Attempting to remove launchd plist from {}", PListPath.string());
+ if (unlink(ServicePath.string().c_str()) == -1)
+ {
+ return MakeErrorCodeFromLastError();;
+ }
+
return {};
}