use super::{Concurrent, ExitStatus, Result, Sigmask, 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<Rc<Concurrent<S>>>) -> PinFuture<'a, Infallible>>;
pub type ChildProcessStarter<S> =
Box<dyn FnOnce(&mut Env<Rc<Concurrent<S>>>, ChildProcessTask<S>) -> Pid>;
pub trait Fork {
fn run_in_child_process<D, F>(&self, shared_data: D, child_task: F) -> (Result<Pid>, D)
where
Self: Sized,
D: Clone + 'static,
F: AsyncFnOnce(Self, D) + 'static;
#[deprecated(
since = "0.14.0",
note = "use the `run_in_child_process` method instead"
)]
fn new_child_process(&self) -> Result<ChildProcessStarter<Self>>
where
Self: Sigmask + 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)
}
}