65 lines · 2.6 KB · Rust
RawDownload
// Copyright 2026 The Jujutsu Authors//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at//// https://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License. //! Common helpers for configuring subprocesses use std::process::Command; /// Keeps a console window from popping up when `jj` is used from a GUI/// application on Windows.////// The flag is only set if the current process has no console. When `jj` runs/// in a terminal, its console is passed down to the child instead. That/// matters for programs that prompt the user, such as `ssh` asking for a key/// passphrase or for confirmation of an unknown host key: those prompts are/// written to the console, not to the inherited standard streams.////// Setting `CREATE_NO_WINDOW` unconditionally gives the child an *invisible*/// console, which the child then happily prompts on, leaving `jj` waiting/// forever for input that the user can neither see nor provide.#[cfg(windows)]pub fn suppress_console_window(command: &mut Command) {    use std::os::windows::process::CommandExt as _;     // Note that `DETACHED_PROCESS` is not used here, even though that's how Git    // hides the window (see `compat/mingw.c`). It leaves the child without a    // console at all, and Win32-OpenSSH then busy-loops in `readpassphrase()`    // when it has to prompt, flooding stderr instead of failing.    const CREATE_NO_WINDOW: u32 = 0x0800_0000;     if !has_console() {        command.creation_flags(CREATE_NO_WINDOW);    }} /// Does nothing on platforms other than Windows.#[cfg(not(windows))]pub fn suppress_console_window(_command: &mut Command) {} /// Returns whether the current process has a console window.////// [`std::io::IsTerminal`] can't be used for this: it is false whenever the/// standard streams are redirected, even though a console is still attached/// and usable for prompting.#[cfg(windows)]#[allow(unsafe_code)]fn has_console() -> bool {    use windows_sys::Win32::System::Console::GetConsoleWindow;     // SAFETY: `GetConsoleWindow()` takes no arguments, has no preconditions,    // and only returns a window handle (or null) without touching any memory    // we own.    let hwnd = unsafe { GetConsoleWindow() };    !hwnd.is_null()}