summaryrefslogtreecommitdiff
path: root/runtime/ops/process.rs
diff options
context:
space:
mode:
authorBert Belder <bertbelder@gmail.com>2021-01-13 20:52:12 -0800
committerBert Belder <bertbelder@gmail.com>2021-01-14 10:26:59 -0800
commit979d71c883ee76c5e1246c5ad02f2791b745bef6 (patch)
tree97e6212460238ed14fa7cf7504f1c70cd311acbb /runtime/ops/process.rs
parentb358426eeae1118e73a5420fbe1b3becdb5371a1 (diff)
refactor: make Process#kill() throw sensible errors on Windows (#9111)
Previously, calling `Process#kill()` after the process had exited would sometimes throw a `TypeError` on Windows. After this patch, it will throw `NotFound` instead, just like other platforms. This patch also fixes flakiness of the `runKillAfterStatus` test on Windows.
Diffstat (limited to 'runtime/ops/process.rs')
-rw-r--r--runtime/ops/process.rs72
1 files changed, 34 insertions, 38 deletions
diff --git a/runtime/ops/process.rs b/runtime/ops/process.rs
index 63e22b601..412d21ef2 100644
--- a/runtime/ops/process.rs
+++ b/runtime/ops/process.rs
@@ -219,23 +219,6 @@ async fn op_run_status(
}))
}
-#[cfg(not(unix))]
-const SIGINT: i32 = 2;
-#[cfg(not(unix))]
-const SIGKILL: i32 = 9;
-#[cfg(not(unix))]
-const SIGTERM: i32 = 15;
-
-#[cfg(not(unix))]
-use winapi::{
- shared::minwindef::DWORD,
- um::{
- handleapi::CloseHandle,
- processthreadsapi::{OpenProcess, TerminateProcess},
- winnt::PROCESS_TERMINATE,
- },
-};
-
#[cfg(unix)]
pub fn kill(pid: i32, signo: i32) -> Result<(), AnyError> {
use nix::sys::signal::{kill as unix_kill, Signal};
@@ -248,30 +231,43 @@ pub fn kill(pid: i32, signo: i32) -> Result<(), AnyError> {
#[cfg(not(unix))]
pub fn kill(pid: i32, signal: i32) -> Result<(), AnyError> {
use std::io::Error;
- match signal {
- SIGINT | SIGKILL | SIGTERM => {
- if pid <= 0 {
- return Err(type_error("unsupported pid"));
- }
- unsafe {
- let handle = OpenProcess(PROCESS_TERMINATE, 0, pid as DWORD);
- if handle.is_null() {
- return Err(Error::last_os_error().into());
- }
- if TerminateProcess(handle, 1) == 0 {
- CloseHandle(handle);
- return Err(Error::last_os_error().into());
- }
- if CloseHandle(handle) == 0 {
- return Err(Error::last_os_error().into());
- }
+ use std::io::ErrorKind::NotFound;
+ use winapi::shared::minwindef::DWORD;
+ use winapi::shared::minwindef::FALSE;
+ use winapi::shared::minwindef::TRUE;
+ use winapi::shared::winerror::ERROR_INVALID_PARAMETER;
+ use winapi::um::errhandlingapi::GetLastError;
+ use winapi::um::handleapi::CloseHandle;
+ use winapi::um::processthreadsapi::OpenProcess;
+ use winapi::um::processthreadsapi::TerminateProcess;
+ use winapi::um::winnt::PROCESS_TERMINATE;
+
+ const SIGINT: i32 = 2;
+ const SIGKILL: i32 = 9;
+ const SIGTERM: i32 = 15;
+
+ if !matches!(signal, SIGINT | SIGKILL | SIGTERM) {
+ Err(type_error("unsupported signal"))
+ } else if pid <= 0 {
+ Err(type_error("unsupported pid"))
+ } else {
+ let handle = unsafe { OpenProcess(PROCESS_TERMINATE, FALSE, pid as DWORD) };
+ if handle.is_null() {
+ let err = match unsafe { GetLastError() } {
+ ERROR_INVALID_PARAMETER => Error::from(NotFound), // Invalid `pid`.
+ errno => Error::from_raw_os_error(errno as i32),
+ };
+ Err(err.into())
+ } else {
+ let r = unsafe { TerminateProcess(handle, 1) };
+ unsafe { CloseHandle(handle) };
+ match r {
+ FALSE => Err(Error::last_os_error().into()),
+ TRUE => Ok(()),
+ _ => unreachable!(),
}
}
- _ => {
- return Err(type_error("unsupported signal"));
- }
}
- Ok(())
}
#[derive(Deserialize)]