gglib_core/utils/
process.rs

1//! Process spawning utilities with consistent cross-platform behaviour.
2//!
3//! On Windows, every child process created with `std::process::Command::new`
4//! inherits a new console window unless `CREATE_NO_WINDOW` is explicitly set.
5//! The `windows_subsystem = "windows"` attribute on the main binary only
6//! suppresses the window for the *main* process — not any child processes.
7//!
8//! Use [`cmd`] and [`async_cmd`] instead of `Command::new` at every call site.
9//! The Windows-specific flag is applied here and nowhere else.
10
11use std::ffi::OsStr;
12
13/// Create a [`std::process::Command`] that will not open a console window on Windows.
14///
15/// Identical to `std::process::Command::new(program)` on macOS and Linux.
16///
17/// # Usage
18///
19/// ```rust,ignore
20/// use gglib_core::utils::process::cmd;
21///
22/// let output = cmd("nvidia-smi").arg("--list-gpus").output()?;
23/// ```
24pub fn cmd(program: impl AsRef<OsStr>) -> std::process::Command {
25    #[allow(unused_mut)]
26    let mut c = std::process::Command::new(program);
27    #[cfg(windows)]
28    {
29        use std::os::windows::process::CommandExt;
30        c.creation_flags(0x08000000); // CREATE_NO_WINDOW
31    }
32    c
33}
34
35/// Create a [`tokio::process::Command`] that will not open a console window on Windows.
36///
37/// Identical to `tokio::process::Command::new(program)` on macOS and Linux.
38///
39/// # Usage
40///
41/// ```rust,ignore
42/// use gglib_core::utils::process::async_cmd;
43///
44/// let child = async_cmd("llama-server").arg("--port").arg("8080").spawn()?;
45/// ```
46pub fn async_cmd(program: impl AsRef<OsStr>) -> tokio::process::Command {
47    #[allow(unused_mut)]
48    let mut c = tokio::process::Command::new(program);
49    #[cfg(windows)]
50    {
51        use std::os::windows::process::CommandExt;
52        c.creation_flags(0x08000000); // CREATE_NO_WINDOW
53    }
54    c
55}