mirror of
https://github.com/openai/codex.git
synced 2026-10-19 17:28:46 +00:00
Suppress Windows console windows for background subprocesses (#49164)
## Why Background helpers launched from a detached Windows process can allocate console windows. Job Object launches and containment fallbacks need to preserve console suppression as well. ## What changed - Add `codex_utils_process::background_command` to set `CREATE_NO_WINDOW` on Windows, and use it across background subprocess launches, including Git, plugins, authentication, diagnostics, and sandbox helpers. - Centralize console suppression in Job Object launches. Keep `CREATE_NO_WINDOW` when retrying without containment, and clear `CREATE_SUSPENDED` so the fallback child can run. - Preserve console inheritance for interactive shell launches and interactive AWS authentication refreshes. ## Testing Add Windows regression tests covering console-free launches from detached parents through standard and Tokio commands, stdout/stderr capture, successful containment, Job Object creation and assignment failures, and sandbox setup refresh helpers. GitOrigin-RevId: b2c238fa7d4f9fbd868e5adf7d4be9958ff01e6c
This commit is contained in:
@@ -23,6 +23,7 @@ doctest = false
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
codex-utils-process = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
clap = { workspace = true, features = ["derive", "env"] }
|
||||
|
||||
@@ -72,7 +72,7 @@ async fn query_channel(wevtutil: &Path, channel: Channel) -> Option<Vec<Evidence
|
||||
.map(|id| format!("EventID={id}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" or ");
|
||||
let mut child = Command::new(wevtutil)
|
||||
let mut child = Command::from(codex_utils_process::background_command(wevtutil))
|
||||
.args(["qe", channel.1])
|
||||
.arg(format!(
|
||||
"/q:*[System[({events}) and TimeCreated[timediff(@SystemTime) <= 604800000]]]"
|
||||
|
||||
@@ -236,7 +236,7 @@ async fn endpoint_products() -> EndpointInspection {
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "windows"))]
|
||||
async fn product_command(program: impl AsRef<OsStr>, args: &[&str]) -> Option<Output> {
|
||||
let mut command = Command::new(program);
|
||||
let mut command = Command::from(codex_utils_process::background_command(program));
|
||||
command
|
||||
.args(args)
|
||||
.stdin(Stdio::null())
|
||||
|
||||
@@ -73,8 +73,17 @@ async fn restrictive_launcher_uses_embedded_if_daemon_cannot_start() -> Result<(
|
||||
.arg("--no-alt-screen")
|
||||
.stdin(std::process::Stdio::inherit())
|
||||
.stdout(std::process::Stdio::inherit())
|
||||
.stderr(std::process::Stdio::inherit());
|
||||
let status = job.spawn_contained(&mut command)?.wait().await?;
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
// This interactive CLI must inherit the PTY console rather than use
|
||||
// the background helper's CREATE_NO_WINDOW launch policy.
|
||||
.creation_flags(windows_sys::Win32::System::Threading::CREATE_SUSPENDED)
|
||||
.kill_on_drop(true);
|
||||
let mut child = command.spawn()?;
|
||||
ensure!(
|
||||
job.assign_and_resume_process(child.id().context("missing CLI pid")?)?,
|
||||
"CLI job assignment failed"
|
||||
);
|
||||
let status = child.wait().await?;
|
||||
ensure!(status.success(), "CLI exited: {status}");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user