diff --git a/src/async_process.rs b/src/async_process.rs index 9bfa4ed..1f0ab4c 100644 --- a/src/async_process.rs +++ b/src/async_process.rs @@ -2,6 +2,7 @@ use std::ffi::OsStr; use std::process::Stdio; use std::{collections::HashMap, os::unix::process::ExitStatusExt}; use tokio::process::Command; +use crate::is_flatpak::IS_FLATPAK; pub struct AsyncProcessOut { pub exit_code: i32, @@ -13,10 +14,25 @@ pub async fn async_process, T: AsRef>( cmd: S, args: Option<&[T]>, env: Option>, + host_spawn: Option, ) -> anyhow::Result { - let cmd = Command::new(cmd) - .args(args.unwrap_or_default()) - .envs(env.unwrap_or_default()) + let mut command: Command; + if *IS_FLATPAK && host_spawn.unwrap_or_default() { + let mut flatpak_env = vec![]; + for (key, value) in env.unwrap_or_default() { + flatpak_env.push(format!("--env={}={}", key, value)); + } + command = Command::new("flatpak-spawn"); + command.arg("--host") + .args(flatpak_env) + .arg(cmd) + .args(args.unwrap_or_default()); + } else { + command = Command::new(cmd); + command.args(args.unwrap_or_default()).envs(env.unwrap_or_default()); + } + + let cmd = command .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) diff --git a/src/build_tools/cmake.rs b/src/build_tools/cmake.rs index 5946ec6..f2d3fc4 100644 --- a/src/build_tools/cmake.rs +++ b/src/build_tools/cmake.rs @@ -26,7 +26,7 @@ impl Cmake { } } args.push(self.source_dir.to_string_lossy().to_string()); - WorkerJob::new_cmd(self.env.clone(), "cmake".into(), Some(args)) + WorkerJob::new_cmd(self.env.clone(), "cmake".into(), Some(args), Some(false)) } pub fn get_build_job(&self) -> WorkerJob { @@ -37,6 +37,7 @@ impl Cmake { "--build".into(), self.build_dir.to_string_lossy().to_string(), ]), + Some(false), ) } @@ -48,6 +49,7 @@ impl Cmake { "--install".into(), self.build_dir.to_string_lossy().to_string(), ]), + Some(false), ) } } diff --git a/src/build_tools/git.rs b/src/build_tools/git.rs index eb5a90c..923b25b 100644 --- a/src/build_tools/git.rs +++ b/src/build_tools/git.rs @@ -13,7 +13,7 @@ impl Git { fn cmd(&self, args: Vec) -> WorkerJob { let mut nargs = vec!["-C".into(), self.dir.to_string_lossy().to_string()]; nargs.extend(args); - WorkerJob::new_cmd(None, "git".into(), Some(nargs)) + WorkerJob::new_cmd(None, "git".into(), Some(nargs), Some(false)) } fn get_repo(&self) -> String { @@ -84,6 +84,7 @@ impl Git { self.dir.to_string_lossy().to_string(), "--recurse-submodules".into(), ]), + Some(false), ) } diff --git a/src/builders/build_basalt.rs b/src/builders/build_basalt.rs index e67e081..cc1bd2e 100644 --- a/src/builders/build_basalt.rs +++ b/src/builders/build_basalt.rs @@ -79,6 +79,7 @@ pub fn get_build_basalt_jobs(profile: &Profile, clean_build: bool) -> VecDeque VecDeque VecDeque { profile.prefix.to_string_lossy().to_string(), get_cache_dir().to_string_lossy().to_string(), ]), + Some(false), )); jobs diff --git a/src/builders/build_openhmd.rs b/src/builders/build_openhmd.rs index 1157eca..3404bbd 100644 --- a/src/builders/build_openhmd.rs +++ b/src/builders/build_openhmd.rs @@ -62,6 +62,7 @@ pub fn get_build_openhmd_jobs(profile: &Profile, clean_build: bool) -> VecDeque< .to_string_lossy() .to_string(), ]), + Some(false), )); } // build job @@ -69,6 +70,7 @@ pub fn get_build_openhmd_jobs(profile: &Profile, clean_build: bool) -> VecDeque< None, "ninja".into(), Some(vec!["-C".into(), build_dir.to_string_lossy().to_string()]), + Some(false), )); // install job jobs.push_back(WorkerJob::new_cmd( @@ -79,6 +81,7 @@ pub fn get_build_openhmd_jobs(profile: &Profile, clean_build: bool) -> VecDeque< build_dir.to_string_lossy().to_string(), "install".into(), ]), + Some(false), )); jobs diff --git a/src/ui/app.rs b/src/ui/app.rs index 1a1d424..d46a7ee 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -34,7 +34,7 @@ use crate::{ }, }, is_flatpak::IS_FLATPAK, linux_distro::LinuxDistro, openxr_prober::is_openxr_ready, paths::get_data_dir, profile::{Profile, XRServiceType}, stateless_action, steam_linux_runtime_injector::{ restore_runtime_entrypoint, set_runtime_entrypoint_launch_opts_from_profile, - }, util::file_utils::{setcap_cap_sys_nice_eip, setcap_cap_sys_nice_eip_cmd}, vulkaninfo::VulkanInfo, xr_devices::XRDevice + }, util::{cmd_utils::make_command, file_utils::{setcap_cap_sys_nice_eip, setcap_cap_sys_nice_eip_cmd}}, vulkaninfo::VulkanInfo, xr_devices::XRDevice }; use adw::{prelude::*, ResponseAppearance}; use gtk::glib::{self, clone}; @@ -43,7 +43,7 @@ use relm4::{ new_action_group, new_stateful_action, new_stateless_action, prelude::*, }; -use std::{collections::{HashMap, VecDeque}, fs::remove_file, process::Command, time::Duration}; +use std::{collections::VecDeque, fs::remove_file, time::Duration}; pub struct App { application: adw::Application, @@ -163,12 +163,7 @@ impl App { self.debug_view.sender().emit(DebugViewMsg::ClearLog); self.xr_devices = vec![]; if *IS_FLATPAK { - Command::new("flatpak-spawn") - .args(vec![ - "--host", - "rm", - prof.xrservice_type.ipc_file_path().to_str().unwrap() - ]) + make_command(String::from("rm"), Some(&[prof.xrservice_type.ipc_file_path().to_str().unwrap()]), None, Some(true)) .output() .expect("Failed to remove xrservice IPC file"); } else { @@ -216,28 +211,12 @@ impl App { let prof = self.get_selected_profile(); if let Some(autostart_cmd) = &prof.autostart_command { let mut jobs = VecDeque::new(); - - if *IS_FLATPAK { - let mut args = vec![String::from("--host")]; - for (key, value) in &prof.environment { - args.push(format!("--env={}={}", key, value)); - } - args.push(String::from("sh")); - args.push(String::from("-c")); - args.push(autostart_cmd.clone()); - - jobs.push_back(WorkerJob::new_cmd( - Some(HashMap::new()), - "flatpak-spawn".into(), - Some(args), - )); - } else { - jobs.push_back(WorkerJob::new_cmd( - Some(prof.environment.clone()), - "sh".into(), - Some(vec!["-c".into(), autostart_cmd.clone()]), - )); - } + jobs.push_back(WorkerJob::new_cmd( + Some(prof.environment.clone()), + "sh".into(), + Some(vec!["-c".into(), autostart_cmd.clone()]), + Some(true) + )); let autostart_worker = JobWorker::new(jobs, sender.input_sender(), |msg| match msg { JobWorkerOut::Log(rows) => Msg::OnServiceLog(rows), JobWorkerOut::Exit(code) => Msg::OnAutostartExit(code), diff --git a/src/ui/install_wivrn_box.rs b/src/ui/install_wivrn_box.rs index cf63f7c..af5b08a 100644 --- a/src/ui/install_wivrn_box.rs +++ b/src/ui/install_wivrn_box.rs @@ -218,6 +218,7 @@ impl AsyncComponent for InstallWivrnBox { "adb", Some(&["install", "-r", "-g", apk_path.to_string_lossy().to_string().as_str()]), None, + None ) .await { diff --git a/src/ui/job_worker/internal_worker.rs b/src/ui/job_worker/internal_worker.rs index cf8ee5d..3b6e35b 100644 --- a/src/ui/job_worker/internal_worker.rs +++ b/src/ui/job_worker/internal_worker.rs @@ -3,12 +3,12 @@ use super::{ state::JobWorkerState, }; use crate::{ - is_flatpak::IS_FLATPAK, profile::{LighthouseDriver, Profile}, ui::SENDER_IO_ERR_MSG + profile::{LighthouseDriver, Profile}, ui::SENDER_IO_ERR_MSG, util::cmd_utils::make_command }; use nix::unistd::Pid; use relm4::{prelude::*, Worker}; use std::{ - collections::{HashMap, VecDeque}, io::{BufRead, BufReader}, mem, os::unix::process::ExitStatusExt, process::{Command, Stdio}, sync::{Arc, Mutex}, thread + collections::VecDeque, io::{BufRead, BufReader}, mem, os::unix::process::ExitStatusExt, process::Stdio, sync::{Arc, Mutex}, thread }; macro_rules! logger_thread { @@ -85,9 +85,7 @@ impl Worker for InternalJobWorker { match &mut job { WorkerJob::Cmd(data) => { let data = data.clone(); - if let Ok(mut cmd) = Command::new(data.command) - .args(data.args) - .envs(data.environment) + if let Ok(mut cmd) = make_command(data.command, Some(&data.args), Some(data.environment), Some(data.host_spawn)) .stdin(Stdio::piped()) .stderr(Stdio::piped()) .stdout(Stdio::piped()) @@ -210,21 +208,12 @@ impl InternalJobWorker { vec![], ), }; - let mut data = CmdWorkerData { + let data = CmdWorkerData { environment: env.clone(), command: command.clone(), args: args.clone(), + host_spawn: true, }; - if *IS_FLATPAK { - data.environment = HashMap::new(); - data.command = String::from("flatpak-spawn"); - data.args = vec![String::from("--host")]; - for (key, value) in env { - data.args.push(format!("--env={}={}", key, value)); - } - data.args.push(command); - data.args.extend(args); - } let mut jobs = VecDeque::new(); jobs.push_back(WorkerJob::Cmd(data)); Self::builder().detach_worker(JobWorkerInit { jobs, state }) diff --git a/src/ui/job_worker/job.rs b/src/ui/job_worker/job.rs index 69c8c1d..39bcc9d 100644 --- a/src/ui/job_worker/job.rs +++ b/src/ui/job_worker/job.rs @@ -7,6 +7,7 @@ pub struct CmdWorkerData { pub environment: HashMap, pub command: String, pub args: Vec, + pub host_spawn: bool, } #[derive(Debug, Clone)] @@ -38,11 +39,13 @@ impl WorkerJob { env: Option>, cmd: String, args: Option>, + host_spawn: Option ) -> Self { Self::Cmd(CmdWorkerData { environment: env.unwrap_or_default(), command: cmd, args: args.unwrap_or_default(), + host_spawn: host_spawn.unwrap_or_default(), }) } diff --git a/src/ui/steamvr_calibration_box.rs b/src/ui/steamvr_calibration_box.rs index ff08b83..cb3ac77 100644 --- a/src/ui/steamvr_calibration_box.rs +++ b/src/ui/steamvr_calibration_box.rs @@ -159,6 +159,7 @@ impl SimpleComponent for SteamVrCalibrationBox { Some(env.clone()), vrcmd.clone(), Some(vec!["--pollposes".into()]), + Some(false), )); JobWorker::new(jobs, sender.input_sender(), |msg| match msg { JobWorkerOut::Log(_) => Self::Input::NoOp, @@ -178,6 +179,7 @@ impl SimpleComponent for SteamVrCalibrationBox { Some(env), vrcmd, Some(vec!["--resetroomsetup".into()]), + Some(false), )); JobWorker::new(jobs, sender.input_sender(), |msg| match msg { JobWorkerOut::Log(_) => Self::Input::NoOp, diff --git a/src/ui/wivrn_wired_start_box.rs b/src/ui/wivrn_wired_start_box.rs index 76b11e4..8736e79 100644 --- a/src/ui/wivrn_wired_start_box.rs +++ b/src/ui/wivrn_wired_start_box.rs @@ -136,6 +136,7 @@ impl AsyncComponent for WivrnWiredStartBox { "adb shell am start -a android.intent.action.VIEW -d \"wivrn+tcp://127.0.0.1\" $PACKAGE" ) ]), + None, None ).await { Ok(out) if out.exit_code == 0 => diff --git a/src/util/cmd_utils.rs b/src/util/cmd_utils.rs new file mode 100644 index 0000000..f7372bb --- /dev/null +++ b/src/util/cmd_utils.rs @@ -0,0 +1,26 @@ +use std::{collections::HashMap, ffi::OsStr, process::Command}; + +use crate::is_flatpak::IS_FLATPAK; + +pub fn make_command, T: AsRef>( + cmd: S, + args: Option<&[T]>, + env: Option>, + host_spawn: Option, +) -> Command { + if *IS_FLATPAK && host_spawn.unwrap_or_default() { + let mut flatpak_env = vec![]; + for (key, value) in env.unwrap_or_default() { + flatpak_env.push(format!("--env={}={}", key, value)); + } + let mut command = Command::new("flatpak-spawn"); + command.arg("--host") + .args(flatpak_env) + .arg(cmd) + .args(args.unwrap_or_default()); + return command; + } + let mut command = Command::new(cmd); + command.args(args.unwrap_or_default()).envs(env.unwrap_or_default()); + command +} \ No newline at end of file diff --git a/src/util/file_utils.rs b/src/util/file_utils.rs index eb6dffd..6bbddd0 100644 --- a/src/util/file_utils.rs +++ b/src/util/file_utils.rs @@ -1,4 +1,4 @@ -use crate::{async_process::async_process, is_flatpak::IS_FLATPAK, profile::Profile}; +use crate::{async_process::async_process, profile::Profile}; use anyhow::bail; use nix::{ errno::Errno, @@ -81,15 +81,7 @@ pub fn setcap_cap_sys_nice_eip_cmd(profile: &Profile) -> Vec { } pub async fn setcap_cap_sys_nice_eip(profile: &Profile) { - let setcap_cmd = setcap_cap_sys_nice_eip_cmd(profile); - if *IS_FLATPAK { - let mut flatpak_cmd = vec!["--host".into(), "pkexec".into()]; - flatpak_cmd.extend(setcap_cmd); - if let Err(e) = async_process("flatpak-spawn", Some(&flatpak_cmd), None).await - { - eprintln!("Error: failed running setcap: {e}"); - } - } else if let Err(e) = async_process("pkexec", Some(&setcap_cmd), None).await + if let Err(e) = async_process("pkexec", Some(&setcap_cap_sys_nice_eip_cmd(profile)), None, Some(true)).await { eprintln!("Error: failed running setcap: {e}"); } diff --git a/src/util/mod.rs b/src/util/mod.rs index 10902df..7a9a5bf 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1,3 +1,4 @@ pub mod file_utils; pub mod hash; pub mod steamvr_utils; +pub mod cmd_utils;