diff --git a/Cargo.toml b/Cargo.toml index 9b2b5975a..b4a37d258 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ is-it-maintained-open-issues = { repository = "fubarnetes/libjail-rs" } [features] serialize = ["serde", "serde_json", "rctl/serialize"] +tokio = ["dep:tokio"] [dependencies] bitflags = "^1" @@ -38,6 +39,7 @@ strum_macros = "0.21.1" serde = { version="1.0", features = ["derive"], optional=true} serde_json = { version="1.0", optional=true } thiserror = "1.0" +tokio = { version = "1.28", features = ["process"], optional = true } [dev-dependencies] cli-table = { version="0.4", default-features=false, features=["derive"] } diff --git a/src/process.rs b/src/process.rs index ff0f316e4..2a15d8608 100644 --- a/src/process.rs +++ b/src/process.rs @@ -2,7 +2,9 @@ use crate::{JailError, RunningJail}; use log::trace; use std::os::unix::process::CommandExt; -use std::process; +use std::process::Command as StdCommand; +#[cfg(feature = "tokio")] +use tokio::process::Command as TokioCommand; /// Extension to the `std::process::Command` builder to run the command in a /// jail. @@ -34,13 +36,32 @@ 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; + fn jail(&mut self, jail: &RunningJail) -> &mut Self; } #[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); +impl Jailed for StdCommand { + fn jail(&mut self, jail: &RunningJail) -> &mut Self { + trace!("std::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 + } +} + +#[cfg(all(target_os = "freebsd", feature = "tokio"))] +impl Jailed for TokioCommand { + fn jail(&mut self, jail: &RunningJail) -> &mut Self { + trace!("tokio::process::Command::jail({:?}, jail={:?})", self, jail); let jail = *jail; unsafe { self.pre_exec(move || {