use crate::Target;
#[cfg(target_os = "linux")]
pub fn run(target: &Target, program: &str, args: &[String]) -> Result<i32, String> {
use crate::filter::{install, program as filter_program};
use std::os::unix::process::CommandExt;
use std::process::Command;
if !cfg!(target_arch = "x86_64") {
return Err("the local runner simulates x86_64 kernels only".to_string());
}
let insns = filter_program(target);
let mut cmd = Command::new(program);
cmd.args(args);
unsafe {
cmd.pre_exec(move || install::apply(&install::Prog::new(&insns)));
}
let status = cmd
.status()
.map_err(|e| format!("cannot start {program} under the seccomp filter: {e}"))?;
Ok(status.code().unwrap_or(128))
}
#[cfg(not(target_os = "linux"))]
pub fn run(_target: &Target, _program: &str, _args: &[String]) -> Result<i32, String> {
Err("the local runner needs a Linux host; use the container runner".to_string())
}
#[cfg(all(test, target_os = "linux", target_arch = "x86_64"))]
mod tests {
use super::*;
use crate::KernelVersion;
#[test]
fn runs_a_program_under_the_filter() {
let target = Target::kernel(KernelVersion::parse("3.10").unwrap());
let ok = run(&target, "/bin/sh", &["-c".into(), "exit 7".into()]);
assert_eq!(ok, Ok(7));
assert!(run(&target, "/no/such/program", &[]).is_err());
}
}