xtask_todo_lib/devshell/sandbox/
run.rs1use std::path::Path;
4use std::process::Command;
5
6use super::super::vfs::Vfs;
7use super::elf::restore_execute_bits_for_build_artifacts;
8use super::error::SandboxError;
9use super::export::export_vfs_to_temp_dir;
10use super::paths::find_in_path;
11use super::sync::{host_export_root, sync_host_dir_to_vfs};
12
13pub fn run_in_export_dir<P: AsRef<Path>>(
21 export_dir: &Path,
22 program: P,
23 args: &[String],
24) -> Result<std::process::ExitStatus, SandboxError> {
25 let mut cmd = Command::new(program.as_ref());
26 cmd.args(args)
27 .current_dir(export_dir)
28 .stdin(std::process::Stdio::inherit())
29 .stdout(std::process::Stdio::inherit())
30 .stderr(std::process::Stdio::inherit());
31
32 #[cfg(target_os = "linux")]
33 if super::linux_mount::linux_mount_namespace_enabled() {
34 super::linux_mount::apply_linux_private_mount_namespace(&mut cmd);
35 }
36
37 let mut child = cmd.spawn().map_err(SandboxError::ExportFailed)?;
38 child.wait().map_err(SandboxError::ExportFailed)
39}
40
41pub fn run_rust_tool(
51 vfs: &mut Vfs,
52 vfs_path: &str,
53 program: &str,
54 args: &[String],
55) -> Result<std::process::ExitStatus, SandboxError> {
56 let export_dir = export_vfs_to_temp_dir(vfs, vfs_path)?;
57 let work_dir = host_export_root(&export_dir, vfs_path);
58 restore_execute_bits_for_build_artifacts(&work_dir)?;
59
60 let program_path = find_in_path(program).ok_or_else(|| {
61 SandboxError::ExportFailed(std::io::Error::new(
62 std::io::ErrorKind::NotFound,
63 format!("{program} not found in PATH"),
64 ))
65 })?;
66 let status = run_in_export_dir(&work_dir, &program_path, args);
67
68 let sync_result = sync_host_dir_to_vfs(&export_dir, vfs_path, vfs);
69 let _ = std::fs::remove_dir_all(&export_dir);
70
71 sync_result?;
72 status
73}