From 992011a4cd9a35f197acc0a0bd430d89a0d01013 Mon Sep 17 00:00:00 2001 From: Small White <364772080@qq.com> Date: Thu, 7 Mar 2024 16:56:21 +0800 Subject: Expose more process info on Windows --- alacritty_terminal/src/tty/windows/child.rs | 25 ++++++++++++++++++++++++- alacritty_terminal/src/tty/windows/mod.rs | 4 ++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/alacritty_terminal/src/tty/windows/child.rs b/alacritty_terminal/src/tty/windows/child.rs index 6bc9ed20..7de6563f 100644 --- a/alacritty_terminal/src/tty/windows/child.rs +++ b/alacritty_terminal/src/tty/windows/child.rs @@ -1,5 +1,6 @@ use std::ffi::c_void; use std::io::Error; +use std::num::NonZeroU32; use std::sync::atomic::{AtomicPtr, Ordering}; use std::sync::{mpsc, Arc, Mutex}; @@ -8,7 +9,7 @@ use polling::{Event, Poller}; use windows_sys::Win32::Foundation::{BOOLEAN, HANDLE}; use windows_sys::Win32::System::Threading::{ - RegisterWaitForSingleObject, UnregisterWait, INFINITE, WT_EXECUTEINWAITTHREAD, + GetProcessId, RegisterWaitForSingleObject, UnregisterWait, INFINITE, WT_EXECUTEINWAITTHREAD, WT_EXECUTEONLYONCE, }; @@ -42,6 +43,8 @@ pub struct ChildExitWatcher { wait_handle: AtomicPtr, event_rx: mpsc::Receiver, interest: Arc>>, + child_handle: HANDLE, + pid: Option, } impl ChildExitWatcher { @@ -66,10 +69,13 @@ impl ChildExitWatcher { if success == 0 { Err(Error::last_os_error()) } else { + let pid = unsafe { NonZeroU32::new(GetProcessId(child_handle)) }; Ok(ChildExitWatcher { wait_handle: AtomicPtr::from(wait_handle as *mut c_void), event_rx, interest, + child_handle, + pid, }) } } @@ -85,6 +91,23 @@ impl ChildExitWatcher { pub fn deregister(&self) { *self.interest.lock().unwrap() = None; } + + /// Retrieve the process handle of the underlying child process. + /// + /// This function does **not** pass ownership of the raw handle to you, + /// and the handle is only guaranteed to be valid while the hosted application + /// has not yet been destroyed. + /// + /// If you terminate the process using this handle, the terminal will get a + /// timeout error, and the child watcher will emit an `Exited` event. + pub fn raw_handle(&self) -> HANDLE { + self.child_handle + } + + /// Retrieve the Process ID associated to the underlying child process. + pub fn pid(&self) -> Option { + self.pid + } } impl Drop for ChildExitWatcher { diff --git a/alacritty_terminal/src/tty/windows/mod.rs b/alacritty_terminal/src/tty/windows/mod.rs index cbd803f1..e42e2b6c 100644 --- a/alacritty_terminal/src/tty/windows/mod.rs +++ b/alacritty_terminal/src/tty/windows/mod.rs @@ -47,6 +47,10 @@ impl Pty { ) -> Self { Self { backend: backend.into(), conout: conout.into(), conin: conin.into(), child_watcher } } + + pub fn child_watcher(&self) -> &ChildExitWatcher { + &self.child_watcher + } } fn with_key(mut event: Event, key: usize) -> Event { -- cgit v1.2.3-54-g00ecf