diff --git a/src/cli.rs b/src/cli.rs index ec21dc66..01479ec1 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -2,6 +2,7 @@ mod generate; mod idle; mod log; mod quit; +mod run_privileged; pub mod screenshot; mod set_log_level; mod unlock; @@ -47,6 +48,8 @@ pub enum Cmd { Screenshot(ScreenshotArgs), /// Inspect/modify the idle (screensaver) settings. Idle(IdleArgs), + /// Run a privileged program + RunPrivileged(RunPrivilegedArgs), #[cfg(feature = "it")] RunTests, } @@ -63,6 +66,13 @@ pub struct IdleArgs { pub command: Option, } +#[derive(Args, Debug)] +pub struct RunPrivilegedArgs { + /// The program to run + #[clap(required = true)] + pub program: Vec, +} + #[derive(Subcommand, Debug)] pub enum IdleCmd { /// Print the idle status. @@ -190,6 +200,7 @@ pub fn main() { Cmd::Screenshot(a) => screenshot::main(cli.global, a), Cmd::Idle(a) => idle::main(cli.global, a), Cmd::Unlock => unlock::main(cli.global), + Cmd::RunPrivileged(a) => run_privileged::main(cli.global, a), #[cfg(feature = "it")] Cmd::RunTests => crate::it::run_tests(), } diff --git a/src/cli/run_privileged.rs b/src/cli/run_privileged.rs new file mode 100644 index 00000000..21370195 --- /dev/null +++ b/src/cli/run_privileged.rs @@ -0,0 +1,30 @@ +use { + crate::{ + cli::{GlobalArgs, RunPrivilegedArgs}, + compositor::WAYLAND_DISPLAY, + logger::Logger, + utils::{errorfmt::ErrorFmt, oserror::OsError}, + }, + uapi::UstrPtr, +}; + +pub fn main(global: GlobalArgs, args: RunPrivilegedArgs) { + Logger::install_stderr(global.log_level.into()); + let mut wd = match std::env::var(WAYLAND_DISPLAY) { + Ok(v) => v, + _ => fatal!("{} is not set", WAYLAND_DISPLAY), + }; + wd.push_str(".jay"); + std::env::set_var(WAYLAND_DISPLAY, &wd); + let mut argv = UstrPtr::new(); + for arg in &args.program { + argv.push(arg.as_str()); + } + let program = args.program[0].as_str(); + let res = uapi::execvp(program, &argv).unwrap_err(); + fatal!( + "Could not execute `{}`: {}", + program, + ErrorFmt(OsError::from(res)) + ); +}