mirror of
https://github.com/openai/codex.git
synced 2026-11-01 19:33:35 +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:
@@ -3,6 +3,8 @@ use std::ffi::OsStr;
|
||||
use std::ffi::OsString;
|
||||
use std::future::Future;
|
||||
use std::io::ErrorKind;
|
||||
#[cfg(windows)]
|
||||
use std::os::windows::process::CommandExt;
|
||||
use std::path::Path;
|
||||
#[cfg(not(unix))]
|
||||
use std::process::Stdio;
|
||||
@@ -27,6 +29,9 @@ use tokio::task::JoinSet;
|
||||
use tokio::time::timeout;
|
||||
use tracing::Span;
|
||||
|
||||
#[cfg(windows)]
|
||||
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
||||
|
||||
use super::CommandShell;
|
||||
use super::ConfiguredHandler;
|
||||
use super::ConfiguredHandlerKind;
|
||||
@@ -221,18 +226,9 @@ pub(crate) async fn run_command(
|
||||
command.current_dir(cwd);
|
||||
|
||||
#[cfg(windows)]
|
||||
let mut process_tree_job = JobObject::create().ok();
|
||||
#[cfg(windows)]
|
||||
let child = match process_tree_job.as_ref() {
|
||||
Some(job) => match job.spawn_contained(&mut command) {
|
||||
Ok(child) => Ok(child),
|
||||
Err(_) => {
|
||||
process_tree_job = None;
|
||||
command.creation_flags(0);
|
||||
command.spawn()
|
||||
}
|
||||
},
|
||||
None => command.spawn(),
|
||||
let (child, process_tree_job) = match JobObject::spawn_background(&mut command) {
|
||||
Ok((child, job)) => (Ok(child), job),
|
||||
Err(error) => (Err(error), None),
|
||||
};
|
||||
#[cfg(not(windows))]
|
||||
let child = command.spawn();
|
||||
@@ -353,6 +349,7 @@ impl Drop for ProcessTreeGuard {
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.creation_flags(CREATE_NO_WINDOW)
|
||||
.spawn();
|
||||
}
|
||||
}
|
||||
@@ -414,6 +411,8 @@ fn build_command(
|
||||
|
||||
#[cfg(unix)]
|
||||
command.process_mode(codex_utils_pty::ProcessMode::NewSession);
|
||||
#[cfg(windows)]
|
||||
command.creation_flags(CREATE_NO_WINDOW);
|
||||
#[cfg(not(unix))]
|
||||
command
|
||||
.env_clear()
|
||||
|
||||
Reference in New Issue
Block a user