use turkos_os_process_lifecycle_owners::spawn; pub const ABI_HEADER: [u8; 8] = *b"TRTABI2\0"; pub struct Executable<'a> { recipe: spawn::Recipe<'a>, required: u64, } impl<'a> Executable<'a> { /// Pure immutable image preflight, before any PID/resource acquisition. /// available comes from the trusted kernel ABI observation, not the user. pub fn new( image: spawn::TrustedImage<'a>, argv: &[&[u8]], env: &[&[u8]], available: u64, ) -> Result { let recipe = spawn::Recipe::new(image, argv, env)?; let mut header = [0u8; 16]; for (i, b) in header.iter_mut().enumerate() { *b = recipe.expected_byte(spawn::Kind::Data, i)?; } if header[..8] != ABI_HEADER { return Err(spawn::Error::Image); } let required = u64::from_le_bytes(header[8..].try_into().unwrap()); turkos_os_user_runtime_abi::compatible(required, available) .map_err(|_| spawn::Error::Image)?; Ok(Self { recipe, required }) } pub fn required(&self) -> u64 { self.required } pub fn into_recipe(self) -> spawn::Recipe<'a> { self.recipe } }