use clap::Parser; use std::ffi::CString; use std::path::PathBuf; use crate::landlock::apply_sandbox_policy_to_current_thread; #[derive(Debug, Parser)] pub struct LandlockCommand { /// It is possible that the cwd used in the context of the sandbox policy /// is different from the cwd of the process to spawn. pub sandbox_policy_cwd: PathBuf, pub sandbox_policy: codex_core::protocol::SandboxPolicy, /// Full command args to run under landlock. #[arg(trailing_var_arg = true)] pub command: Vec, } pub fn run_main() -> ! { let LandlockCommand { sandbox_policy_cwd, sandbox_policy, command, } = LandlockCommand::parse(); if let Err(e) = apply_sandbox_policy_to_current_thread(&sandbox_policy, &sandbox_policy_cwd) { panic!("error running landlock: {e:?}"); } if command.is_empty() { panic!("No command specified to execute."); } #[expect(clippy::expect_used)] let c_command = CString::new(command[0].as_str()).expect("Failed to convert command to CString"); #[expect(clippy::expect_used)] let c_args: Vec = command .iter() .map(|arg| CString::new(arg.as_str()).expect("Failed to convert arg to CString")) .collect(); let mut c_args_ptrs: Vec<*const libc::c_char> = c_args.iter().map(|arg| arg.as_ptr()).collect(); c_args_ptrs.push(std::ptr::null()); unsafe { libc::execvp(c_command.as_ptr(), c_args_ptrs.as_ptr()); } // If execvp returns, there was an error. let err = std::io::Error::last_os_error(); panic!("Failed to execvp {}: {err}", command[0].as_str()); }