makepad/libs/relax/compiler/tests/std/os_pre_exec.rs
Admin b22a714840 makepad run: the Rust JIT (libs/relax) and makepad-remote
The JIT that runs makepad apps from source: lexer, front end, type checker,
lazy borrow checker (Gandalf; `--check-first` opts in), codegen, session and
warm/cold caches keyed by compiler stamp, provided crates bound late,
startup images, live patching. User-facing name is `makepad run` (binary
`makepad`, MAKEPAD_RUN_* env, ~/.makepad-run); libs/relax stays the internal
library name. `makepad check` reports rustc-style diagnostics with rustc
error codes and checks a whole workspace (`--workspace`). Runs on macOS,
Linux, Windows and Android. makepad-remote: one tool schema for apps and the
WM (app/1): grabs, captures, traces, frame profiles and tweaks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 12:26:21 +02:00

34 lines
1.8 KiB
Rust

// std::os::unix::process::CommandExt::pre_exec: the closure runs in the child before exec; its
// error aborts the spawn and comes back from spawn() (EINVAL when it has no OS code).
use std::os::unix::process::CommandExt;
use std::process::{Command, Stdio};
#[test]
fn a01_pre_exec_runs_in_child() {
let dir = std::env::temp_dir().join(format!("relax-pre-exec-{}", std::process::id()));
std::fs::create_dir_all(&dir).unwrap();
let canon = std::fs::canonicalize(&dir).unwrap();
let d2 = canon.clone();
let out = unsafe {
Command::new("pwd").stdout(Stdio::piped()).pre_exec(move || std::env::set_current_dir(&d2)).output().unwrap()
};
let got = String::from_utf8_lossy(&out.stdout).trim().to_string();
println!("| child cwd matches {} status {}", got == canon.to_str().unwrap(), out.status.success());
println!("| parent cwd unchanged {}", std::env::current_dir().unwrap() != canon);
std::fs::remove_dir(&dir).unwrap();
}
#[test]
fn a02_pre_exec_errors() {
let r = unsafe { Command::new("true").pre_exec(|| Err(std::io::Error::from_raw_os_error(2))).spawn() };
println!("| os error {:?}", r.map(|_| ()).map_err(|e| (e.kind(), e.raw_os_error())));
let r = unsafe { Command::new("true").pre_exec(|| Err(std::io::Error::new(std::io::ErrorKind::Other, "custom"))).spawn() };
println!("| custom error {:?}", r.map(|_| ()).map_err(|e| (e.kind(), e.raw_os_error())));
let mut n = 0;
let st = unsafe {
Command::new("sh").arg("-c").arg("exit 3").pre_exec(move || { n += 1; Ok(()) }).pre_exec(|| Ok(())).status().unwrap()
};
println!("| two closures status {:?}", st.code());
let r = unsafe { Command::new("/nonexistent/program").pre_exec(|| Ok(())).spawn() };
println!("| exec failure {:?}", r.map(|_| ()).map_err(|e| e.kind()));
}