From 368fb049a4e66b8a6dc61938558d0865e8f88c66 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Wed, 18 Sep 2024 10:43:26 +0200 Subject: wip --- src/zenutil/service.cpp | 142 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 108 insertions(+), 34 deletions(-) (limited to 'src/zenutil/service.cpp') 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(" "); + ProgramArguments.Append(" "); AppendEscaped(Argument, ProgramArguments); ProgramArguments.Append("\n"); } @@ -149,27 +150,38 @@ namespace { "\n" "\n" "\n" - " \n" - " Label\n" - " {}\n" // ServiceName - " ProgramArguments\n" - " \n" - " {}\n" // Program name + "\n" + " Label\n" + " {}\n" // DaemonName + " \n" + " ProgramArguments\n" + " \n" + " {}\n" // Program name "{}" // "arg\n" * number of arguments - " \n" - " KeepAlive\n" - " \n" - " StandardOutPath\n" - " /var/log/myjob.log\n" - " StandardErrorPath\n" - " /var/log/myjob.log\n" - " Debug\n" - " <{}/>\n" - " \n" + " \n" + " \n" + " RunAtLoad\n" + " \n" + " \n" +// " KeepAlive\n" +// " \n" +// " \n" + " StandardOutPath\n" + " /var/log/{}.log\n" + " \n" + " StandardErrorPath\n" + " /var/log/{}.err.log\n" + " \n" + " Debug\n" + " <{}/>\n" + " \n" + "\n" "\n", - ServiceName, - ExecutablePath.filename().string(), + DaemonName, + ExecutablePath.string(), ProgramArguments.ToView(), + ServiceName, + ServiceName, Debug ? "true"sv : "false"sv); // "Sockets" @@ -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 {}; } -- cgit v1.2.3