use anyhow::{Context, Result};
mod execution_packs;
mod self_test;
pub(crate) use execution_packs::*;
pub(crate) use self_test::*;
pub(crate) fn current_binary() -> Result<std::path::PathBuf> {
let exe = std::env::current_exe().context("locate current executable")?;
std::fs::canonicalize(&exe).with_context(|| {
format!(
"resolve current executable symlink target for {}",
exe.display()
)
})
}
#[cfg(unix)]
pub(crate) fn process_is_running(pid: u32) -> bool {
if pid == std::process::id() {
return false;
}
let Ok(pid) = libc::pid_t::try_from(pid) else {
return false;
};
if pid <= 0 {
return false;
}
let rc = unsafe { libc::kill(pid, 0) };
if rc == 0 {
return true;
}
std::io::Error::last_os_error().raw_os_error() == Some(libc::EPERM)
}
#[cfg(windows)]
pub(crate) fn process_is_running(pid: u32) -> bool {
use std::ffi::c_void;
if pid == std::process::id() {
return false;
}
const PROCESS_QUERY_LIMITED_INFORMATION: u32 = 0x1000;
#[link(name = "kernel32")]
extern "system" {
fn OpenProcess(dwDesiredAccess: u32, bInheritHandle: i32, dwProcessId: u32) -> *mut c_void;
fn CloseHandle(hObject: *mut c_void) -> i32;
fn GetLastError() -> u32;
}
let handle = unsafe { OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid) };
if handle.is_null() {
const ERROR_INVALID_PARAMETER: u32 = 87;
return unsafe { GetLastError() } != ERROR_INVALID_PARAMETER;
}
unsafe {
CloseHandle(handle);
}
true
}
#[cfg(not(any(unix, windows)))]
pub(crate) fn process_is_running(_pid: u32) -> bool {
false
}