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; } #[derive(Debug)] pub struct StdCommandRunner; impl CommandRunner for StdCommandRunner { fn run_with_args(&self, program: &str, args: &[&str]) -> IoResult { // 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 } } } impl<'a, C> CommandRunner for UserCommandRunner<'a, C> where C: 'a + CommandRunner { fn run_with_args(&self, program: &str, args: &[&str]) -> IoResult { let mut new_args = vec![self.user_name, "-s", "/usr/bin/env", "--", program]; new_args.extend_from_slice(args); self.command_runner.run_with_args("su", &new_args) } } #[cfg(test)] mod test { }