use clap::Parser;
use std::ffi::CString;
use std::path::PathBuf;
use crate::product::linux_sandbox::landlock::apply_sandbox_policy_to_current_thread;
#[derive(Debug, Parser)]
pub struct LandlockCommand {
#[arg(long = "sandbox-policy-cwd")]
pub sandbox_policy_cwd: PathBuf,
#[arg(long = "sandbox-policy")]
pub sandbox_policy: crate::product::agent::protocol::SandboxPolicy,
#[arg(trailing_var_arg = true)]
pub command: Vec<String>,
}
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<CString> = 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());
}
let err = std::io::Error::last_os_error();
panic!("Failed to execvp {}: {err}", command[0].as_str());
}