From e477f3b5cd0653155845eb80f923090bccf6249e Mon Sep 17 00:00:00 2001 From: Tw Date: Mon, 16 Aug 2021 20:19:05 +0800 Subject: [PATCH] fix(child-process): unexpected pane closing issue with nushell (#648) * fix unexpected pane closing issue with nushell nushell doesn't create a new process group when spawnning a process, so all processes including the ones spwanned by us are in the same foreground group. So if kernel will send signal to every member of this group. This patch fixes this issue by creating a new foreground process group when spawnning a new terminal pane. Fix #615 Signed-off-by: Tw * add comment about unsafe Co-authored-by: Aram Drevekenin --- zellij-server/src/os_input_output.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/zellij-server/src/os_input_output.rs b/zellij-server/src/os_input_output.rs index 24d40583..198a1487 100644 --- a/zellij-server/src/os_input_output.rs +++ b/zellij-server/src/os_input_output.rs @@ -1,5 +1,6 @@ use std::env; use std::os::unix::io::RawFd; +use std::os::unix::process::CommandExt; use std::path::PathBuf; use std::process::{Child, Command}; use std::sync::{Arc, Mutex}; @@ -102,10 +103,21 @@ fn handle_terminal(cmd: RunCommand, orig_termios: termios::Termios) -> (RawFd, P let pid_secondary = match fork_pty_res.fork_result { ForkResult::Parent { child } => child, ForkResult::Child => { - let child = Command::new(cmd.command) - .args(&cmd.args) - .spawn() - .expect("failed to spawn"); + let child = unsafe { + Command::new(cmd.command) + .args(&cmd.args) + .pre_exec(|| -> std::io::Result<()> { + // this is the "unsafe" part, for more details please see: + // https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html#notes-and-safety + unistd::setpgid(Pid::from_raw(0), Pid::from_raw(0)) + .expect("failed to create a new process group"); + Ok(()) + }) + .spawn() + .expect("failed to spawn") + }; + unistd::tcsetpgrp(0, Pid::from_raw(child.id() as i32)) + .expect("faled to set child's forceground process group"); handle_command_exit(child); ::std::process::exit(0); }