From df21af3522625167e538e7d9be9de1a6ea5ed69e Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Mon, 1 Aug 2022 18:19:37 +0800 Subject: [PATCH] while executing external command, make it as foreground --- crates/nu-command/src/system/run_external.rs | 4 ++ crates/nu-system/Cargo.toml | 4 +- crates/nu-system/src/foreground.rs | 45 ++++++++++++++++++++ crates/nu-system/src/lib.rs | 2 + crates/nu_plugin_bin_reader/Cargo.toml | 8 ++++ crates/nu_plugin_bin_reader/src/main.rs | 3 ++ 6 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 crates/nu-system/src/foreground.rs create mode 100644 crates/nu_plugin_bin_reader/Cargo.toml create mode 100644 crates/nu_plugin_bin_reader/src/main.rs diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index cfc47da660..f8327a3f75 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -13,6 +13,7 @@ use nu_protocol::{Category, Example, ListStream, PipelineData, RawStream, Span, use itertools::Itertools; use nu_engine::CallExt; +use nu_system::external_process_setup::{reset_foreground_id, set_foreground, setup_fg_external}; use pathdiff::diff_paths; use regex::Regex; @@ -140,6 +141,7 @@ impl ExternalCommand { #[cfg(not(windows))] { + setup_fg_external(&mut process); child = process.spawn() } @@ -150,6 +152,7 @@ impl ExternalCommand { self.name.span, )), Ok(mut child) => { + set_foreground(&child); if !input.is_nothing() { let mut engine_state = engine_state.clone(); let mut stack = stack.clone(); @@ -296,6 +299,7 @@ impl ExternalCommand { span: head, }); } + reset_foreground_id(); Ok(()) } } diff --git a/crates/nu-system/Cargo.toml b/crates/nu-system/Cargo.toml index d46e63e5de..8c473691b6 100644 --- a/crates/nu-system/Cargo.toml +++ b/crates/nu-system/Cargo.toml @@ -13,7 +13,7 @@ name = "ps" path = "src/main.rs" [dependencies] - +libc = "0.2" [target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] procfs = "0.13.0" @@ -21,11 +21,9 @@ procfs = "0.13.0" [target.'cfg(target_os = "macos")'.dependencies] libproc = "0.12.0" errno = "0.2" -libc = "0.2" [target.'cfg(target_os = "windows")'.dependencies] winapi = { version = "0.3.9", features = ["tlhelp32", "fileapi", "handleapi", "ifdef", "ioapiset", "minwindef", "pdh", "psapi", "synchapi", "sysinfoapi", "winbase", "winerror", "winioctl", "winnt", "oleauto", "wbemcli", "rpcdce", "combaseapi", "objidl", "powerbase", "netioapi", "lmcons", "lmaccess", "lmapibuf", "memoryapi", "shellapi", "std", "securitybaseapi"] } chrono = "0.4" -libc = "0.2" ntapi = "0.3" once_cell = "1.0" diff --git a/crates/nu-system/src/foreground.rs b/crates/nu-system/src/foreground.rs new file mode 100644 index 0000000000..cec793fe76 --- /dev/null +++ b/crates/nu-system/src/foreground.rs @@ -0,0 +1,45 @@ +// It's a simpler version for fish shell's external process handling. +// +// For more information, please check `child_setup_process` function in fish shell. +// https://github.com/fish-shell/fish-shell/blob/3f90efca38079922b4b21707001d7bb9630107eb/src/postfork.cpp#L140 +#[cfg(target_family = "unix")] +pub mod external_process_setup { + use std::os::unix::prelude::CommandExt; + pub fn setup_fg_external(external_command: &mut std::process::Command) { + unsafe { + libc::signal(libc::SIGTTOU, libc::SIG_IGN); + libc::signal(libc::SIGTTIN, libc::SIG_IGN); + + external_command.pre_exec(|| { + libc::setpgid(0, 0); + Ok(()) + }); + } + } + + pub fn set_foreground(process: &std::process::Child) -> i32 { + unsafe { + let my_id = libc::getpid(); + libc::tcsetpgrp(0, process.id() as i32); + my_id + } + } + + pub fn reset_foreground_id() { + unsafe { + libc::tcsetpgrp(libc::STDIN_FILENO, libc::getpgrp()); + libc::signal(libc::SIGTTOU, libc::SIG_DFL); + libc::signal(libc::SIGTTIN, libc::SIG_DFL); + } + } +} + +#[cfg(target_family = "windows")] +mod external_process_setup { + + pub fn setup_fg_external(external_command: &mut std::process::Command) {} + + pub fn set_foreground(process: &std::process::Child) -> i32 {} + + pub fn reset_foreground_id() {} +} diff --git a/crates/nu-system/src/lib.rs b/crates/nu-system/src/lib.rs index 1ad89d73d5..ce228c782b 100644 --- a/crates/nu-system/src/lib.rs +++ b/crates/nu-system/src/lib.rs @@ -4,6 +4,7 @@ mod linux; mod macos; #[cfg(target_os = "windows")] mod windows; +mod foreground; #[cfg(any(target_os = "android", target_os = "linux"))] pub use self::linux::*; @@ -11,3 +12,4 @@ pub use self::linux::*; pub use self::macos::*; #[cfg(target_os = "windows")] pub use self::windows::*; +pub use self::foreground::external_process_setup; diff --git a/crates/nu_plugin_bin_reader/Cargo.toml b/crates/nu_plugin_bin_reader/Cargo.toml new file mode 100644 index 0000000000..6e32b9d7ff --- /dev/null +++ b/crates/nu_plugin_bin_reader/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "nu_plugin_bin_reader" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/crates/nu_plugin_bin_reader/src/main.rs b/crates/nu_plugin_bin_reader/src/main.rs new file mode 100644 index 0000000000..e7a11a969c --- /dev/null +++ b/crates/nu_plugin_bin_reader/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +}