use super::{ExitStatus, Result, Signals};
use crate::Env;
#[cfg(all(doc, unix))]
use crate::RealSystem;
#[cfg(doc)]
use crate::VirtualSystem;
use crate::job::Pid;
use crate::job::ProcessState;
use std::convert::Infallible;
use std::ffi::{CStr, CString};
use std::pin::Pin;
use std::rc::Rc;
pub trait GetPid {
#[must_use]
fn getpid(&self) -> Pid;
#[must_use]
fn getppid(&self) -> Pid;
#[must_use]
fn getpgrp(&self) -> Pid;
fn getsid(&self, pid: Pid) -> Result<Pid>;
}
impl<S: GetPid> GetPid for Rc<S> {
#[inline]
fn getpid(&self) -> Pid {
(self as &S).getpid()
}
#[inline]
fn getppid(&self) -> Pid {
(self as &S).getppid()
}
#[inline]
fn getpgrp(&self) -> Pid {
(self as &S).getpgrp()
}
#[inline]
fn getsid(&self, pid: Pid) -> Result<Pid> {
(self as &S).getsid(pid)
}
}
pub trait SetPgid {
fn setpgid(&self, pid: Pid, pgid: Pid) -> Result<()>;
}
impl<S: SetPgid> SetPgid for Rc<S> {
#[inline]
fn setpgid(&self, pid: Pid, pgid: Pid) -> Result<()> {
(self as &S).setpgid(pid, pgid)
}
}
type PinFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
pub type ChildProcessTask<S> = Box<dyn for<'a> FnOnce(&'a mut Env<S>) -> PinFuture<'a, Infallible>>;
pub type ChildProcessStarter<S> = Box<dyn FnOnce(&mut Env<S>, ChildProcessTask<S>) -> Pid>;
pub trait Fork {
fn new_child_process(&self) -> Result<ChildProcessStarter<Self>>
where
Self: Sized;
}
pub trait Wait: Signals {
fn wait(&self, target: Pid) -> Result<Option<(Pid, ProcessState)>>;
}
impl<S: Wait> Wait for Rc<S> {
#[inline]
fn wait(&self, target: Pid) -> Result<Option<(Pid, ProcessState)>> {
(self as &S).wait(target)
}
}
pub trait Exec {
fn execve(
&self,
path: &CStr,
args: &[CString],
envs: &[CString],
) -> impl Future<Output = Result<Infallible>> + use<Self>;
}
impl<S: Exec> Exec for Rc<S> {
#[inline]
fn execve(
&self,
path: &CStr,
args: &[CString],
envs: &[CString],
) -> impl Future<Output = Result<Infallible>> + use<S> {
(self as &S).execve(path, args, envs)
}
}
pub trait Exit {
fn exit(&self, exit_status: ExitStatus) -> impl Future<Output = Infallible> + use<Self>;
}
impl<S: Exit> Exit for Rc<S> {
#[inline]
fn exit(&self, exit_status: ExitStatus) -> impl Future<Output = Infallible> + use<S> {
(self as &S).exit(exit_status)
}
}