use crate::{
alloc::CBox,
core::{
optional::{gen_optional, NSTDOptional},
slice::NSTDSlice,
str::NSTDStr,
},
io::NSTDIOError,
NSTDInt32, NSTDUInt32,
};
use nstdapi::nstdapi;
use std::process::{Child, Command};
#[nstdapi]
pub struct NSTDChildProcess {
proc: CBox<Child>,
}
gen_optional!(NSTDOptionalChildProcess, NSTDChildProcess);
#[nstdapi]
pub unsafe fn nstd_proc_spawn(
program: &NSTDStr,
args: &NSTDSlice,
vars: &NSTDSlice,
) -> NSTDOptionalChildProcess {
let mut cmd = Command::new(program.as_str());
if let Some(args) = args.as_slice::<NSTDStr>() {
if let Some(vars) = vars.as_slice::<[NSTDStr; 2]>() {
cmd.args(args.iter().map(|arg| arg.as_str()));
cmd.envs(vars.iter().map(|vars| {
(
vars.get_unchecked(0).as_str(),
vars.get_unchecked(1).as_str(),
)
}));
if let Ok(proc) = cmd.spawn() {
if let Some(proc) = CBox::new(proc) {
return NSTDOptional::Some(NSTDChildProcess { proc });
}
}
}
}
NSTDOptional::None
}
#[inline]
#[nstdapi]
pub fn nstd_proc_child_id(handle: &NSTDChildProcess) -> NSTDUInt32 {
handle.proc.id()
}
#[inline]
#[nstdapi]
pub fn nstd_proc_kill(handle: &mut NSTDChildProcess) -> NSTDIOError {
if let Err(err) = handle.proc.kill() {
return NSTDIOError::from_err(err.kind());
}
NSTDIOError::NSTD_IO_ERROR_NONE
}
#[nstdapi]
pub fn nstd_proc_join(handle: &mut NSTDChildProcess) -> NSTDIOError {
match handle.proc.wait() {
Ok(status) if status.success() => NSTDIOError::NSTD_IO_ERROR_NONE,
Err(err) => NSTDIOError::from_err(err.kind()),
_ => NSTDIOError::NSTD_IO_ERROR_UNKNOWN,
}
}
#[inline]
#[nstdapi]
#[allow(
unused_variables,
clippy::missing_const_for_fn,
clippy::needless_pass_by_value
)]
pub fn nstd_proc_free(handle: NSTDChildProcess) {}
#[inline]
#[nstdapi]
pub fn nstd_proc_exit(exit_code: NSTDInt32) -> ! {
std::process::exit(exit_code);
}
#[inline]
#[nstdapi]
pub fn nstd_proc_abort() -> ! {
std::process::abort();
}
#[inline]
#[nstdapi]
pub fn nstd_proc_id() -> NSTDUInt32 {
std::process::id()
}