#[cfg(unix)]
pub fn hostname() -> Option<String> {
let mut buf = [0u8; 256];
let result = unsafe { libc::gethostname(buf.as_mut_ptr() as *mut libc::c_char, buf.len()) };
if result != 0 {
return None;
}
let end = buf.iter().position(|&b| b == 0).unwrap_or(buf.len());
Some(String::from_utf8_lossy(&buf[..end]).into_owned())
}
#[cfg(target_os = "wasi")]
pub const HOST_PID_VAR: &str = "HAYSON_HOST_PID";
#[cfg(target_os = "wasi")]
pub const HOST_NAME_VAR: &str = "HAYSON_HOST_NAME";
#[cfg(target_os = "wasi")]
fn from_env(name: &str) -> Option<String> {
std::env::var(name).ok().filter(|value| !value.is_empty())
}
#[cfg(target_os = "wasi")]
pub fn hostname() -> Option<String> {
static HOST: std::sync::OnceLock<Option<String>> = std::sync::OnceLock::new();
HOST.get_or_init(|| from_env(HOST_NAME_VAR)).clone()
}
#[cfg(all(not(unix), not(target_os = "wasi")))]
pub fn hostname() -> Option<String> {
None
}
#[cfg(unix)]
pub fn pid() -> Option<u32> {
Some(std::process::id())
}
#[cfg(target_os = "wasi")]
pub fn pid() -> Option<u32> {
static PID: std::sync::OnceLock<Option<u32>> = std::sync::OnceLock::new();
*PID.get_or_init(|| from_env(HOST_PID_VAR).and_then(|raw| raw.parse().ok()))
}
#[cfg(all(not(unix), not(target_os = "wasi")))]
pub fn pid() -> Option<u32> {
None
}
#[cfg(unix)]
pub fn process_alive(pid: u32) -> Option<bool> {
#[cfg(test)]
if !tests::accelerator_enabled() {
return None;
}
Some(unsafe { libc::kill(pid as libc::pid_t, 0) == 0 })
}
#[cfg(not(unix))]
pub fn process_alive(_pid: u32) -> Option<bool> {
None
}
#[cfg(test)]
pub mod tests {
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard};
static ENABLED: AtomicBool = AtomicBool::new(true);
static SWITCH: RwLock<()> = RwLock::new(());
pub(super) fn accelerator_enabled() -> bool {
ENABLED.load(Ordering::SeqCst)
}
pub struct WithoutPidLiveness(#[allow(dead_code)] RwLockWriteGuard<'static, ()>);
impl Drop for WithoutPidLiveness {
fn drop(&mut self) {
ENABLED.store(true, Ordering::SeqCst);
}
}
pub fn without_pid_liveness() -> WithoutPidLiveness {
let guard = SWITCH.write().unwrap_or_else(PoisonError::into_inner);
ENABLED.store(false, Ordering::SeqCst);
WithoutPidLiveness(guard)
}
pub fn with_pid_liveness() -> RwLockReadGuard<'static, ()> {
SWITCH.read().unwrap_or_else(PoisonError::into_inner)
}
}