while executing external command, make it as foreground

This commit is contained in:
WindSoilder 2022-08-01 18:19:37 +08:00
parent 2ac7a4d48d
commit df21af3522
6 changed files with 63 additions and 3 deletions

View File

@ -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(())
}
}

View File

@ -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"

View File

@ -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() {}
}

View File

@ -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;

View File

@ -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]

View File

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}