use std::ffi::{OsStr, OsString};
use std::os::unix::ffi::OsStrExt;
use heim_common::prelude::*;
use crate::sys::macos::{pid_exists, wrappers};
use crate::{Pid, ProcessError, ProcessResult};
#[derive(Debug)]
pub struct Command(wrappers::ProcArgs);
impl Command {
pub fn to_os_string(&self) -> OsString {
self.0.to_command()
}
pub fn into_os_string(self) -> OsString {
self.to_os_string()
}
}
impl<'a> IntoIterator for &'a Command {
type Item = &'a OsStr;
type IntoIter = CommandIter<'a>;
fn into_iter(self) -> Self::IntoIter {
CommandIter(self.0.arguments())
}
}
#[derive(Debug)]
pub struct CommandIter<'a>(wrappers::ProcArgsArguments<'a>);
impl<'a> Iterator for CommandIter<'a> {
type Item = &'a OsStr;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(OsStr::from_bytes)
}
}
pub fn command(pid: Pid) -> impl Future<Output = ProcessResult<Command>> {
future::lazy(move |_| wrappers::ProcArgs::get(pid))
.map_ok(Command)
.or_else(move |e| {
match e.raw_os_error() {
Some(libc::EINVAL) => {
let f = pid_exists(pid).and_then(move |is_exists| {
if is_exists {
future::err(ProcessError::ZombieProcess(pid))
} else {
future::err(e.into())
}
});
future::Either::Left(f)
}
_ => {
let f = future::err(e.into());
future::Either::Right(f)
}
}
})
}