You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
57 lines
1.7 KiB
57 lines
1.7 KiB
use std::io::Result as IoResult;
|
|
use std::process::Command;
|
|
use std::process::Output;
|
|
|
|
pub trait CommandRunner {
|
|
fn run_with_args(&self, program: &str, args: &[&str]) -> IoResult<Output>;
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct StdCommandRunner;
|
|
|
|
impl CommandRunner for StdCommandRunner {
|
|
fn run_with_args(&self, program: &str, args: &[&str]) -> IoResult<Output> {
|
|
// FIXME: logger
|
|
println!("{} {:?}", program, args);
|
|
let res = Command::new(program).args(args).output();
|
|
println!("{:?}", res);
|
|
res
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct UserCommandRunner<'a, C> where C: 'a + CommandRunner {
|
|
command_runner: &'a C,
|
|
user_name: &'a str
|
|
}
|
|
|
|
impl<'a, C> UserCommandRunner<'a, C> where C: 'a + CommandRunner {
|
|
pub fn new(user_name: &'a str, command_runner: &'a C) -> UserCommandRunner<'a, C> {
|
|
UserCommandRunner {
|
|
command_runner: command_runner,
|
|
user_name: user_name
|
|
}
|
|
}
|
|
}
|
|
|
|
use std::os::unix::process::CommandExt;
|
|
use std::env;
|
|
use users::get_user_by_name;
|
|
|
|
impl<'a, C> CommandRunner for UserCommandRunner<'a, C> where C: 'a + CommandRunner {
|
|
fn run_with_args(&self, program: &str, args: &[&str]) -> IoResult<Output> {
|
|
let uid = get_user_by_name(self.user_name).unwrap().uid();
|
|
let old_home = env::var("HOME");
|
|
env::set_var("HOME", format!("/home/{}", self.user_name));
|
|
let old_dbus = env::var("DBUS_SESSION_BUS_ADDRESS");
|
|
env::set_var("DBUS_SESSION_BUS_ADDRESS", format!("unix:path=/run/user/{}/bus", uid));
|
|
let res = Command::new(program).uid(uid).gid(uid).args(args).output();
|
|
if let Ok(dbus) = old_dbus { env::set_var("DBUS_SESSION_BUS_ADDRESS", dbus); }
|
|
if let Ok(home) = old_home { env::set_var("HOME", home); }
|
|
res
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
}
|