use platform::process::{self, Process};
use profile::Profile;
use std::collections::HashMap;
use std::convert::AsRef;
use std::env;
use std::ffi::{CString, OsStr};
use std::io;
pub use platform::{ChildSandbox, Sandbox};
pub trait SandboxMethods {
fn profile(&self) -> &Profile;
fn start(&self, command: &mut Command) -> io::Result<Process>;
}
pub trait ChildSandboxMethods {
fn activate(&self) -> Result<(),()>;
}
fn cstring<T>(path: T) -> CString
where T: AsRef<OsStr>
{
let path = path.as_ref();
let bytes = if cfg!(windows) {
path.to_str().unwrap().as_bytes()
} else {
use std::os::unix::ffi::OsStrExt;
path.as_bytes()
};
CString::new(bytes).unwrap()
}
pub struct Command {
pub module_path: CString,
pub args: Vec<CString>,
pub env: HashMap<CString,CString>,
}
impl Command {
pub fn new<T>(module_path: T) -> Command where T: AsRef<OsStr> {
Command {
module_path: cstring(module_path),
args: Vec::new(),
env: HashMap::new(),
}
}
pub fn me() -> io::Result<Command> {
Ok(Command::new(try!(env::current_exe())))
}
pub fn arg<'a,T>(&'a mut self, arg: T) -> &'a mut Command where T: AsRef<OsStr> {
self.args.push(cstring(arg));
self
}
pub fn args<'a,T>(&'a mut self, args: &[T]) -> &'a mut Command where T: AsRef<OsStr> {
self.args.extend(args.iter().map(cstring));
self
}
pub fn env<'a,T,U>(&'a mut self, key: T, val: U) -> &'a mut Command
where T: AsRef<OsStr>, U: AsRef<OsStr> {
self.env.insert(cstring(key), cstring(val));
self
}
pub fn spawn(&self) -> io::Result<Process> {
process::spawn(self)
}
}