diff options
| author | Dan Engelbrecht <[email protected]> | 2024-09-18 10:43:26 +0200 |
|---|---|---|
| committer | Dan Engelbrecht <[email protected]> | 2024-09-18 10:43:36 +0200 |
| commit | 368fb049a4e66b8a6dc61938558d0865e8f88c66 (patch) | |
| tree | 331ccab91c11be43341228ffcadb0912ce36e559 /src/zenutil/service.cpp | |
| parent | Add ServiceSpec struct (diff) | |
| download | zen-368fb049a4e66b8a6dc61938558d0865e8f88c66.tar.xz zen-368fb049a4e66b8a6dc61938558d0865e8f88c66.zip | |
wip
Diffstat (limited to 'src/zenutil/service.cpp')
| -rw-r--r-- | src/zenutil/service.cpp | 142 |
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 {}; } |