diff --git a/Cargo.lock b/Cargo.lock index 09ed90954d..3cc2883670 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,9 +113,8 @@ dependencies = [ [[package]] name = "alacritty_terminal" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ceabf6fc76511f616ca216b51398a2511f19ba9f71bcbd977999edff1b0d1" +version = "0.22.1-dev" +source = "git+https://github.com/alacritty/alacritty?rev=992011a4cd9a35f197acc0a0bd430d89a0d01013#992011a4cd9a35f197acc0a0bd430d89a0d01013" dependencies = [ "base64 0.21.4", "bitflags 2.4.2", diff --git a/crates/terminal/Cargo.toml b/crates/terminal/Cargo.toml index 4686266557..61a5fd8929 100644 --- a/crates/terminal/Cargo.toml +++ b/crates/terminal/Cargo.toml @@ -14,7 +14,8 @@ doctest = false [dependencies] -alacritty_terminal = "0.22.0" +# TODO: when new version of this crate is released, change it +alacritty_terminal = { git = "https://github.com/alacritty/alacritty", rev = "992011a4cd9a35f197acc0a0bd430d89a0d01013" } anyhow.workspace = true collections.workspace = true dirs = "4.0.0" diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 6f5ad36ec4..ddcf8f9428 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -38,10 +38,14 @@ use procinfo::LocalProcessInfo; use serde::{Deserialize, Serialize}; use settings::Settings; use smol::channel::{Receiver, Sender}; +#[cfg(target_os = "windows")] +use std::num::NonZeroU32; use task::TaskId; use terminal_settings::{AlternateScroll, Shell, TerminalBlink, TerminalSettings}; use theme::{ActiveTheme, Theme}; use util::truncate_and_trailoff; +#[cfg(target_os = "windows")] +use windows::Win32::{Foundation::HANDLE, System::Threading::GetProcessId}; use std::{ cmp::{self, min}, @@ -402,7 +406,14 @@ impl TerminalBuilder { // todo(windows) #[cfg(windows)] - let (fd, shell_pid) = (-1, 0); + let (fd, shell_pid) = { + let child = pty.child_watcher(); + let handle = child.raw_handle(); + let pid = child.pid().unwrap_or_else(|| unsafe { + NonZeroU32::new_unchecked(GetProcessId(HANDLE(handle))) + }); + (handle, u32::from(pid)) + }; //And connect them together let event_loop = EventLoop::new( @@ -667,13 +678,31 @@ impl Terminal { /// Updates the cached process info, returns whether the Zed-relevant info has changed fn update_process_info(&mut self) -> bool { #[cfg(unix)] - let mut pid = unsafe { libc::tcgetpgrp(self.shell_fd as i32) }; - // todo(windows) + let pid = { + let ret = unsafe { libc::tcgetpgrp(self.shell_fd as i32) }; + if ret < 0 { + self.shell_pid as i32 + } else { + ret + } + }; + #[cfg(windows)] - let mut pid = unsafe { windows::Win32::System::Threading::GetCurrentProcessId() } as i32; - if pid < 0 { - pid = self.shell_pid as i32; - } + let pid = { + let ret = unsafe { GetProcessId(HANDLE(self.shell_fd as _)) }; + // the GetProcessId may fail and returns zero, which will lead to a stack overflow issue + if ret == 0 { + // in the builder process, there is a small chance, almost negligible, + // that this value could be zero, which means child_watcher returns None, + // GetProcessId returns 0. + if self.shell_pid == 0 { + return false; + } + self.shell_pid + } else { + ret + } + } as i32; if let Some(process_info) = LocalProcessInfo::with_root_pid(pid as u32) { let res = self