From 64c8add3417e51cd7ce8caa45a8dbb4b9ce8e6ad Mon Sep 17 00:00:00 2001 From: Medcl Date: Tue, 20 Feb 2024 11:24:57 +0800 Subject: [PATCH] fix: service start/stop on MacOS (#19) --- src/launchd.rs | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/launchd.rs b/src/launchd.rs index 8fcb607..b3dc9ab 100644 --- a/src/launchd.rs +++ b/src/launchd.rs @@ -1,9 +1,8 @@ use super::{ - utils, ServiceInstallCtx, ServiceLevel, ServiceManager, ServiceStartCtx, ServiceStopCtx, - ServiceUninstallCtx, + utils, ServiceInstallCtx, ServiceLevel, ServiceManager, ServiceStartCtx, + ServiceStopCtx, ServiceUninstallCtx, }; -use plist::Dictionary; -use plist::Value; +use plist::{Dictionary, Value}; use std::{ ffi::OsStr, io, @@ -77,6 +76,16 @@ impl LaunchdServiceManager { user: self.user, } } + + fn get_plist_path(&self, qualified_name: String) -> PathBuf { + let dir_path = if self.user { + user_agent_dir_path().unwrap() + } else { + global_daemon_dir_path() + }; + let plist_path = dir_path.join(format!("{}.plist", qualified_name)); + plist_path + } } impl ServiceManager for LaunchdServiceManager { @@ -121,24 +130,24 @@ impl ServiceManager for LaunchdServiceManager { } fn uninstall(&self, ctx: ServiceUninstallCtx) -> io::Result<()> { - let dir_path = if self.user { - user_agent_dir_path()? - } else { - global_daemon_dir_path() - }; - let qualified_name = ctx.label.to_qualified_name(); - let plist_path = dir_path.join(format!("{}.plist", qualified_name)); + let plist_path = self.get_plist_path(ctx.label.to_qualified_name()); launchctl("unload", plist_path.to_string_lossy().as_ref())?; std::fs::remove_file(plist_path) } fn start(&self, ctx: ServiceStartCtx) -> io::Result<()> { + let plist_path = self.get_plist_path(ctx.label.to_qualified_name()); + + launchctl("load", plist_path.to_string_lossy().as_ref())?; launchctl("start", &ctx.label.to_qualified_name()) } fn stop(&self, ctx: ServiceStopCtx) -> io::Result<()> { - launchctl("stop", &ctx.label.to_qualified_name()) + let plist_path = self.get_plist_path(ctx.label.to_qualified_name()); + + let _ =launchctl("stop", &ctx.label.to_qualified_name()); + launchctl("unload", plist_path.to_string_lossy().as_ref()) } fn level(&self) -> ServiceLevel { @@ -192,7 +201,12 @@ fn global_daemon_dir_path() -> PathBuf { fn user_agent_dir_path() -> io::Result { Ok(dirs::home_dir() - .ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "Unable to locate home directory"))? + .ok_or_else(|| { + io::Error::new( + io::ErrorKind::NotFound, + "Unable to locate home directory", + ) + })? .join("Library") .join("LaunchAgents")) } @@ -200,7 +214,7 @@ fn user_agent_dir_path() -> io::Result { fn make_plist<'a>( config: &LaunchdInstallConfig, label: &str, - args: impl Iterator, + args: impl Iterator, username: Option, working_directory: Option, environment: Option>,