diff --git a/src/platform/macos.rs b/src/platform/macos.rs index b9db741e1..22a1085f6 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -42,9 +42,16 @@ static PRIVILEGES_SCRIPTS_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/src/platform/privileges_scripts"); static mut LATEST_SEED: i32 = 0; -// Using a fixed temporary directory for updates is preferable to -// using one that includes the custom client name. -const UPDATE_TEMP_DIR: &str = "/tmp/.rustdeskupdate"; +#[inline] +fn get_update_temp_dir() -> PathBuf { + let euid = unsafe { hbb_common::libc::geteuid() }; + Path::new("/tmp").join(format!(".rustdeskupdate-{}", euid)) +} + +#[inline] +fn get_update_temp_dir_string() -> String { + get_update_temp_dir().to_string_lossy().into_owned() +} /// Global mutex to serialize CoreGraphics cursor operations. /// This prevents race conditions between cursor visibility (hide depth tracking) @@ -285,21 +292,6 @@ fn update_daemon_agent(agent_plist_file: String, update_source_dir: String, sync _ => { let installed = std::path::Path::new(&agent_plist_file).exists(); log::info!("Agent file {} installed: {}", &agent_plist_file, installed); - if installed { - // Unload first, or load may not work if already loaded. - // We hope that the load operation can immediately trigger a start. - std::process::Command::new("launchctl") - .args(&["unload", "-w", &agent_plist_file]) - .stdin(Stdio::null()) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - .ok(); - let status = std::process::Command::new("launchctl") - .args(&["load", "-w", &agent_plist_file]) - .status(); - log::info!("launch server, status: {:?}", &status); - } } } }; @@ -418,7 +410,9 @@ pub fn set_cursor_pos(x: i32, y: i32) -> bool { let _guard = match CG_CURSOR_MUTEX.try_lock() { Ok(guard) => guard, Err(std::sync::TryLockError::WouldBlock) => { - log::error!("[BUG] set_cursor_pos: CG_CURSOR_MUTEX is already held - potential deadlock!"); + log::error!( + "[BUG] set_cursor_pos: CG_CURSOR_MUTEX is already held - potential deadlock!" + ); debug_assert!(false, "Re-entrant call to set_cursor_pos detected"); return false; } @@ -825,7 +819,8 @@ pub fn quit_gui() { #[inline] pub fn try_remove_temp_update_dir(dir: Option<&str>) { - let target_path = Path::new(dir.unwrap_or(UPDATE_TEMP_DIR)); + let target_path_buf = dir.map(PathBuf::from).unwrap_or_else(get_update_temp_dir); + let target_path = target_path_buf.as_path(); if target_path.exists() { std::fs::remove_dir_all(target_path).ok(); } @@ -901,25 +896,28 @@ end run } pub fn update_from_dmg(dmg_path: &str) -> ResultType<()> { + let update_temp_dir = get_update_temp_dir_string(); println!("Starting update from DMG: {}", dmg_path); - extract_dmg(dmg_path, UPDATE_TEMP_DIR)?; + extract_dmg(dmg_path, &update_temp_dir)?; println!("DMG extracted"); - update_extracted(UPDATE_TEMP_DIR)?; + update_extracted(&update_temp_dir)?; println!("Update process started"); Ok(()) } pub fn update_to(_file: &str) -> ResultType<()> { - update_extracted(UPDATE_TEMP_DIR)?; + let update_temp_dir = get_update_temp_dir_string(); + update_extracted(&update_temp_dir)?; Ok(()) } pub fn extract_update_dmg(file: &str) { + let update_temp_dir = get_update_temp_dir_string(); let mut evt: HashMap<&str, String> = HashMap::from([("name", "extract-update-dmg".to_string())]); - match extract_dmg(file, UPDATE_TEMP_DIR) { + match extract_dmg(file, &update_temp_dir) { Ok(_) => { - log::info!("Extracted dmg file to {}", UPDATE_TEMP_DIR); + log::info!("Extracted dmg file to {}", update_temp_dir); } Err(e) => { evt.insert("err", e.to_string()); diff --git a/src/platform/privileges_scripts/update.scpt b/src/platform/privileges_scripts/update.scpt index 88f4bdde5..07dadb7c6 100644 --- a/src/platform/privileges_scripts/update.scpt +++ b/src/platform/privileges_scripts/update.scpt @@ -14,8 +14,12 @@ on run {daemon_file, agent_file, user, cur_pid, source_dir} set write_daemon_plist to "echo " & quoted form of daemon_file & " > " & daemon_plist & " && chown root:wheel " & daemon_plist & ";" set write_agent_plist to "echo " & quoted form of agent_file & " > " & agent_plist & " && chown root:wheel " & agent_plist & ";" set load_service to "launchctl load -w " & daemon_plist & ";" + set agent_label_cmd to "agent_label=$(basename " & quoted form of agent_plist & " .plist);" + set bootstrap_agent to "if [ -n \"$uid\" ]; then launchctl bootstrap gui/$uid " & quoted form of agent_plist & " 2>/dev/null || launchctl bootstrap user/$uid " & quoted form of agent_plist & " 2>/dev/null || launchctl load -w " & quoted form of agent_plist & " || true; else launchctl load -w " & quoted form of agent_plist & " || true; fi;" + set kickstart_agent to "if [ -n \"$uid\" ]; then launchctl kickstart -k gui/$uid/$agent_label 2>/dev/null || launchctl kickstart -k user/$uid/$agent_label 2>/dev/null || true; fi;" + set load_agent to agent_label_cmd & bootstrap_agent & kickstart_agent - set sh to "set -e;" & resolve_uid & unload_agent & unload_service & kill_others & copy_files & write_daemon_plist & write_agent_plist & load_service + set sh to "set -e;" & resolve_uid & unload_agent & unload_service & kill_others & copy_files & write_daemon_plist & write_agent_plist & load_service & load_agent do shell script sh with prompt "RustDesk wants to update itself" with administrator privileges end run