aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLiam Mitchell <[email protected]>2026-01-15 18:33:20 -0800
committerGitHub Enterprise <[email protected]>2026-01-15 18:33:20 -0800
commit7d5d4093a04a989eca2118938ece7e44097dc3d1 (patch)
treee4803b94e0d3977303342a341482cc2da774d62c /src
parent5.7.16 (diff)
parentRun clang-format on service.cpp (diff)
downloadzen-7d5d4093a04a989eca2118938ece7e44097dc3d1.tar.xz
zen-7d5d4093a04a989eca2118938ece7e44097dc3d1.zip
Merge pull request #701 from ue-foundation/lm/mac-daemon-mode
Implement final changes required for daemon mode on Mac
Diffstat (limited to 'src')
-rw-r--r--src/zen/cmds/service_cmd.cpp22
-rw-r--r--src/zenutil/service.cpp54
2 files changed, 35 insertions, 41 deletions
diff --git a/src/zen/cmds/service_cmd.cpp b/src/zen/cmds/service_cmd.cpp
index 8be76de7c..aa6bfb436 100644
--- a/src/zen/cmds/service_cmd.cpp
+++ b/src/zen/cmds/service_cmd.cpp
@@ -37,9 +37,9 @@ namespace zen {
namespace {
#if ZEN_PLATFORM_WINDOWS
- BOOL IsElevated()
+ BOOL RequiresElevation()
{
- BOOL fRet = FALSE;
+ BOOL fRet = TRUE;
HANDLE hToken = NULL;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
@@ -47,7 +47,7 @@ namespace {
DWORD cbSize = sizeof(TOKEN_ELEVATION);
if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize))
{
- fRet = Elevation.TokenIsElevated;
+ fRet = !Elevation.TokenIsElevated;
}
}
if (hToken)
@@ -102,9 +102,13 @@ namespace {
}
}
-#else // ZEN_PLATFORM_WINDOWS
+#elif ZEN_PLATFORM_MAC
- bool IsElevated() { return geteuid() == 0; }
+ bool RequiresElevation() { return false; } // Mac service mode commands can run without elevation
+
+#else
+
+ bool RequiresElevation() { return geteuid() != 0; }
#endif // ZEN_PLATFORM_WINDOWS
@@ -344,7 +348,7 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
if (SubOption == &m_InstallOptions)
{
- if (!IsElevated())
+ if (RequiresElevation())
{
RunElevated(m_AllowElevation);
return;
@@ -553,7 +557,7 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
throw std::runtime_error(fmt::format("Service '{}' is running, stop before uninstalling", m_ServiceName));
}
- if (!IsElevated())
+ if (RequiresElevation())
{
RunElevated(m_AllowElevation);
return;
@@ -585,7 +589,7 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
return;
}
- if (!IsElevated())
+ if (RequiresElevation())
{
RunElevated(m_AllowElevation);
return;
@@ -617,7 +621,7 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
return;
}
- if (!IsElevated())
+ if (RequiresElevation())
{
RunElevated(m_AllowElevation);
return;
diff --git a/src/zenutil/service.cpp b/src/zenutil/service.cpp
index 103fdaa2f..f2a925e61 100644
--- a/src/zenutil/service.cpp
+++ b/src/zenutil/service.cpp
@@ -229,12 +229,13 @@ namespace {
std::filesystem::path GetPListPath(const std::string& DaemonName)
{
- const std::filesystem::path PListFolder = "/Library/LaunchDaemons";
+ char* HomeDir = getenv("HOME");
+ std::filesystem::path PListFolder = HomeDir;
+ PListFolder /= "Library/LaunchAgents";
return PListFolder / (DaemonName + ".plist");
}
- std::string BuildPlist(std::string_view ServiceName,
- const std::filesystem::path& ExecutablePath,
+ std::string BuildPlist(const std::filesystem::path& ExecutablePath,
std::string_view CommandLineOptions,
std::string_view DaemonName,
bool Debug)
@@ -265,14 +266,8 @@ namespace {
" <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"
+ " <key>KeepAlive</key>\n"
+ " <true/>\n"
" \n"
" <key>Debug</key>\n"
" <{}/>\n"
@@ -282,22 +277,7 @@ namespace {
DaemonName,
ExecutablePath,
ProgramArguments.ToView(),
- ServiceName,
- ServiceName,
Debug ? "true"sv : "false"sv);
-
- // "<key>Sockets</key>"
- // "<dict>"
- // "<key>Listeners</key>"
- // "<dict>"
- // "<key>SockServiceName</key>"
- // "<string>{}</string>" // Listen socket
- // "<key>SockType</key>"
- // "<string>tcp</string>"
- // "<key>SockFamily</key>"
- // "<string>IPv4</string>"
- // "</dict>"
- // "</dict>"
}
#endif // ZEN_PLATFORM_MAC
@@ -752,9 +732,8 @@ StopService(std::string_view ServiceName)
std::error_code
InstallService(std::string_view ServiceName, const ServiceSpec& Spec)
{
- // TODO: Do we need to create a separate user for the service or is running as the default service user OK?
const std::string DaemonName = GetDaemonName(ServiceName);
- std::string PList = BuildPlist(ServiceName, Spec.ExecutablePath, Spec.CommandLineOptions, DaemonName, true);
+ std::string PList = BuildPlist(Spec.ExecutablePath, Spec.CommandLineOptions, DaemonName, true);
const std::filesystem::path PListPath = GetPListPath(DaemonName);
ZEN_INFO("Writing launchd plist to {}", PListPath.string());
@@ -910,8 +889,14 @@ StartService(std::string_view ServiceName)
{
const std::string DaemonName = GetDaemonName(ServiceName);
const std::filesystem::path PListPath = GetPListPath(DaemonName);
+ std::pair<int, std::string> User = ExecuteProgram("id -u");
+
+ if (User.first != 0)
+ {
+ return MakeErrorCode(User.first);
+ }
- std::pair<int, std::string> Res = ExecuteProgram(fmt::format("launchctl bootstrap system {}", PListPath));
+ std::pair<int, std::string> Res = ExecuteProgram(fmt::format("launchctl bootstrap gui/{} {}", User.second, PListPath));
if (Res.first != 0)
{
return MakeErrorCode(Res.first);
@@ -926,13 +911,18 @@ StopService(std::string_view ServiceName)
const std::string DaemonName = GetDaemonName(ServiceName);
const std::filesystem::path PListPath = GetPListPath(DaemonName);
- /*
- std::pair<int, std::string> Res = ExecuteProgram(fmt::format("launchctl bootout system ", PListPath.));
+ std::pair<int, std::string> User = ExecuteProgram("id -u");
+
+ if (User.first != 0)
+ {
+ return MakeErrorCode(User.first);
+ }
+
+ std::pair<int, std::string> Res = ExecuteProgram(fmt::format("launchctl bootout gui/{} {}", User.second, PListPath));
if (Res.first != 0)
{
return MakeErrorCode(Res.first);
}
- */
return {};
}