pub use crate::stdlib::sandbox::{
active_backend_available, active_backend_name, active_workspace_process_env,
check_fs_path_scope, command_output, deterministic_message_locale_env, enforce_process_cwd,
process_spawn_error, process_violation_error, push_process_sandbox_scope, render_policy_root,
std_command_for, tokio_command_for, FsAccess, ProcessCommandConfig, ProcessSandboxScope,
ProcessSandboxScopeGuard, SandboxViolation, MESSAGE_LOCALE_OVERRIDE_ENV,
};
pub fn wrapped_spawn_io_error(exit_code: i32, stderr: &[u8]) -> Option<std::io::Error> {
crate::stdlib::sandbox::active_sandbox_policy()?;
if !active_backend_available() {
return None;
}
#[cfg(target_os = "macos")]
return macos_wrapped_spawn_io_error(exit_code, stderr);
#[cfg(not(target_os = "macos"))]
{
let _ = (exit_code, stderr);
None
}
}
#[cfg(target_os = "macos")]
pub(crate) fn macos_wrapped_spawn_io_error(
exit_code: i32,
stderr: &[u8],
) -> Option<std::io::Error> {
const EX_OSERR: i32 = 71;
const PREFIX: &str = "sandbox-exec: execvp() of '";
const SUFFIX: &str = "' failed: No such file or directory\n";
let stderr = std::str::from_utf8(stderr).ok()?;
if exit_code == EX_OSERR && stderr.starts_with(PREFIX) && stderr.ends_with(SUFFIX) {
return Some(std::io::Error::from_raw_os_error(libc::ENOENT));
}
None
}
#[cfg(all(test, target_os = "macos"))]
mod tests {
use super::macos_wrapped_spawn_io_error;
#[test]
fn wrapper_missing_program_is_typed_not_found() {
let error = macos_wrapped_spawn_io_error(
71,
b"sandbox-exec: execvp() of 'missing-command' failed: No such file or directory\n",
)
.expect("sandbox wrapper failure");
assert_eq!(error.kind(), std::io::ErrorKind::NotFound);
}
#[test]
fn genuine_exit_71_is_not_a_wrapper_failure() {
assert!(macos_wrapped_spawn_io_error(71, b"").is_none());
assert!(macos_wrapped_spawn_io_error(71, b"application failed\n").is_none());
}
}