1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
//! Jail-Specific extensions to the `std::process` module use std::process; use std::os::unix::process::CommandExt; use JailError; use RunningJail; /// Extension to the `std::process::Command` builder to run the command in a /// jail. /// /// Adds a `before_exec` hook to the `std::process::Command` builder that calls /// the `jail_attach`(2) syscall. /// /// # Examples /// /// ``` /// # use std::process::Command; /// use jail::process::Jailed; /// /// # let jail = jail::StoppedJail::new("/rescue") /// # .name("testjail_process") /// # .start() /// # .expect("could not start jail"); /// # /// let output = Command::new("/hostname") /// .jail(&jail) /// .output() /// .expect("Failed to execute command"); /// /// println!("output: {:?}", output.stdout); /// # jail.kill().expect("could not stop jail"); /// ``` #[cfg(target_os = "freebsd")] pub trait Jailed { /// Sets the child process to be executed within a jail. This translates /// to calling `jail_attach` in the child process. Failure in the /// `jail_attach` call will cause the spawn to fail. fn jail(&mut self, jail: &RunningJail) -> &mut process::Command; } #[cfg(target_os = "freebsd")] impl Jailed for process::Command { fn jail(&mut self, jail: &RunningJail) -> &mut process::Command { trace!("process::Command::jail({:?}, jail={:?})", self, jail); let jail = *jail; unsafe { self.pre_exec(move || { trace!("pre_exec handler: attaching"); jail.attach().map_err(|err| match err { JailError::JailAttachError(e) => e, _ => panic!("jail.attach() failed with unexpected error"), }) }); } self } }