mirror of
https://github.com/Tencent/BrowserSkill.git
synced 2026-09-10 13:01:23 +08:00
fix(windows): preserve pipe continuity and verify process liveness
This commit is contained in:
@@ -90,17 +90,21 @@ pub fn pid_alive(pid: u32) -> bool {
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use windows_sys::Win32::Foundation::CloseHandle;
|
||||
use windows_sys::Win32::Foundation::{CloseHandle, WAIT_TIMEOUT};
|
||||
use windows_sys::Win32::System::Threading::{
|
||||
OpenProcess, PROCESS_QUERY_LIMITED_INFORMATION,
|
||||
OpenProcess, PROCESS_SYNCHRONIZE, WaitForSingleObject,
|
||||
};
|
||||
unsafe {
|
||||
let handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid);
|
||||
let handle = OpenProcess(PROCESS_SYNCHRONIZE, 0, pid);
|
||||
if handle.is_null() {
|
||||
return false;
|
||||
}
|
||||
// An exited process can still be opened while another handle
|
||||
// keeps its kernel object alive. Poll its termination signal;
|
||||
// unlike checking STILL_ACTIVE, this also handles exit code 259.
|
||||
let alive = WaitForSingleObject(handle, 0) == WAIT_TIMEOUT;
|
||||
CloseHandle(handle);
|
||||
true
|
||||
alive
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,3 +114,39 @@ pub fn pid_alive(pid: u32) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, windows))]
|
||||
mod tests {
|
||||
use super::pid_alive;
|
||||
use std::os::windows::process::CommandExt;
|
||||
use std::process::Command;
|
||||
|
||||
#[test]
|
||||
fn current_process_is_alive() {
|
||||
assert!(pid_alive(std::process::id()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_process_is_not_alive() {
|
||||
assert!(!pid_alive(0));
|
||||
assert!(!pid_alive(u32::MAX));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exited_process_with_retained_handle_is_not_alive() {
|
||||
for exit_code in [0, 259] {
|
||||
let mut child = Command::new("cmd.exe")
|
||||
.args(["/D", "/C", &format!("exit {exit_code}")])
|
||||
.creation_flags(0x0800_0000) // CREATE_NO_WINDOW
|
||||
.spawn()
|
||||
.expect("spawn short-lived process");
|
||||
assert_eq!(child.wait().unwrap().code(), Some(exit_code));
|
||||
// Keep Child (and its process handle) alive during the probe.
|
||||
assert!(
|
||||
!pid_alive(child.id()),
|
||||
"exited process with code {exit_code}"
|
||||
);
|
||||
drop(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user