// SAFETY: We are setting the PGID of this (child) process to detach it from the group of the parent so signals are not propagated from the parent.
unsafe{
ifsetpgid(0,to)!=0{
returnErr(io::Error::last_os_error());
}
}
Ok(())
}
}
/// Spawn the process, and contain its standard output.
///
/// # Notes
@ -69,19 +89,28 @@ where U: IntoIterator<Item=V>,
letstderr=std::process::Stdio::inherit();
}
};
letmutchild=matchCommand::new(process)
letmutchild=Command::new(process);
letchild=child
.args(process_args.iter_cloned().map(|x|x.into_owned()))//Do we need `into_owned()` here?
.args(args)
.args(args.into_iter())
.stdout(std::process::Stdio::piped())
.stderr(stderr)
.stdin(std::process::Stdio::null())
.spawn(){
Ok(chi)=>chi,
Err(sp)=>{
returnErr(Error::Spawning(sp));
}
};
.kill_on_drop(false);
// SAFETY: This is only calling `setpgid()`.
unsafe{
child
.pre_exec(set_process_group(0))// NOTE: .process_group() does not exist in this version, so we hack it together outselves and call `setpgid()` directly
shutdown_tx.broadcast(Some(res.clone())).expect("Failed to communicate worker shutdown with waiters");
res
});
handle
@ -542,6 +543,22 @@ pub enum Error
Unknown,
}
implError
{
/// If this error comes from an attempt to communicate with the worker that failed but can be ignored.
///
/// # Usage
/// If the worker has been gracefully shutdown, and background tasks are still running that want to update the progress, an error will be returned when those already extant tasks attempt to send the commands to do so.
/// Those tasks can ignore those errors entirely if this function returns `true`.
todo!("XXX: How to actually implement this? Add global mutexed counter in `Process` itself to track them and optionally await on them? We have prevented any more from spawning, but how do we wait for the ones that already are (which is the whole point of this.)");
// We do not have the results, return an empty iterator