use std::path::{Path, PathBuf};
use heim_common::prelude::*;
use crate::Pid;
use super::{pid_exists, pids};
use crate::{ProcessState};
use crate::types::EnvOs;
mod stat;
mod procfs;
#[derive(Debug)]
pub struct Process {
stat: stat::Stat,
exe: Option<PathBuf>,
}
impl Process {
pub fn from_pid(pid: Pid) -> impl Future<Item=Process, Error=Error> {
Process::from_path(format!("/proc/{}/", pid))
}
pub fn from_path<T>(path: T) -> impl Future<Item=Process, Error=Error>
where T: AsRef<Path> + Send + Clone + 'static
{
let stat = stat::Stat::from_path(path.as_ref().join("stat"));
let exe = procfs::read_exe(path.clone());
stat.join(exe)
.map(|(stat, exe)| {
Process {
stat,
exe,
}
})
}
pub fn pid(&self) -> Pid {
self.stat.pid()
}
pub fn ppid(&self) -> Pid {
self.stat.ppid()
}
pub fn name(&self) -> &str {
self.stat.name()
}
pub fn exe(&self) -> Option<&Path> {
self.exe.as_ref().map(|path| path.as_path())
}
pub fn state(&self) -> ProcessState {
self.stat.state()
}
pub fn is_alive(&self) -> impl Future<Item=bool, Error=Error> {
pid_exists(self.stat.pid())
}
}
pub fn processes() -> impl Stream<Item=Process, Error=Error> {
pids().and_then(Process::from_pid)
}