mirror of
https://github.com/openai/codex.git
synced 2026-10-18 17:18:52 +00:00
## Why Sibling tests can spawn children while an executable fixture is open for writing, allowing inherited writable descriptors to cause `ETXTBSY` when launching the fixture. ## What changed Add a shared `copy_executable` helper for the daemon, doctor path safety, and exec-server tests. On Linux, run `/bin/cp` in a separate process and wait for it to exit before launching the fixture, then restore the source permissions to account for restrictive umasks. Keep `std::fs::copy` on other platforms. GitOrigin-RevId: 88f36826bbc6ab4e16e28ff02d5e7d6bd8dbf793
40 lines
1.4 KiB
Rust
40 lines
1.4 KiB
Rust
//! Copies executable fixtures without exposing writable descriptors to sibling test spawns.
|
|
//! Linux copies finish in a separate process before the fixture can be launched.
|
|
|
|
use std::path::Path;
|
|
#[cfg(target_os = "linux")]
|
|
use std::process::Command;
|
|
|
|
#[cfg(target_os = "linux")]
|
|
use anyhow::Context;
|
|
use anyhow::Result;
|
|
#[cfg(target_os = "linux")]
|
|
use anyhow::ensure;
|
|
|
|
pub(super) fn copy_executable(source: &Path, destination: &Path) -> Result<()> {
|
|
#[cfg(target_os = "linux")]
|
|
{
|
|
// Sibling tests can spawn children while a copy holds the executable open
|
|
// for writing. Keep that descriptor in a separate process and wait for it
|
|
// to exit, so inherited descriptors cannot cause ETXTBSY during launch.
|
|
let output = Command::new("/bin/cp")
|
|
.arg("--")
|
|
.arg(source)
|
|
.arg(destination)
|
|
.output()
|
|
.context("failed to start fixture executable copy")?;
|
|
ensure!(
|
|
output.status.success(),
|
|
"failed to copy fixture executable {} to {}: {}",
|
|
source.display(),
|
|
destination.display(),
|
|
String::from_utf8_lossy(&output.stderr)
|
|
);
|
|
// Match fs::copy even when the test process has a restrictive umask.
|
|
std::fs::set_permissions(destination, std::fs::metadata(source)?.permissions())?;
|
|
}
|
|
#[cfg(not(target_os = "linux"))]
|
|
std::fs::copy(source, destination)?;
|
|
Ok(())
|
|
}
|