wait for children and report return code #37
42
src/lib.rs
42
src/lib.rs
@ -17,17 +17,19 @@ use std::path::Path;
|
|||||||
|
|
||||||
use nix::fcntl::OFlag;
|
use nix::fcntl::OFlag;
|
||||||
use nix::sys::socket;
|
use nix::sys::socket;
|
||||||
use nix::unistd;
|
use nix::sys::wait::{waitpid, WaitPidFlag, WaitStatus};
|
||||||
|
use nix::unistd::{self, Pid};
|
||||||
|
|
||||||
pub struct RunArgs<'a> {
|
pub struct RunArgs<'a> {
|
||||||
pub spec: Option<&'a Path>,
|
pub spec: Option<&'a Path>,
|
||||||
pub debug: bool,
|
pub debug: bool,
|
||||||
|
pub daemon: bool,
|
||||||
|
|
||||||
pub binary: &'a Path,
|
pub binary: &'a Path,
|
||||||
pub binary_args: Vec<&'a str>,
|
pub binary_args: Vec<&'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(args: &RunArgs) -> Result<()> {
|
pub fn run(args: &RunArgs) -> Result<i32> {
|
||||||
// parse the specification
|
// parse the specification
|
||||||
let spec: Specification = if let Some(m) = args.spec {
|
let spec: Specification = if let Some(m) = args.spec {
|
||||||
if m.extension().map(|e| e == "json") == Some(true) {
|
if m.extension().map(|e| e == "json") == Some(true) {
|
||||||
@ -62,7 +64,41 @@ pub fn run(args: &RunArgs) -> Result<()> {
|
|||||||
}
|
}
|
||||||
.spawn()?;
|
.spawn()?;
|
||||||
|
|
||||||
Ok(())
|
if args.daemon {
|
||||||
|
return Ok(exitcode::OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("spawned successfully, awaiting children exiting...");
|
||||||
|
let mut exit_code = exitcode::OK;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let status = match waitpid(Some(Pid::from_raw(-1)), Some(WaitPidFlag::WEXITED)) {
|
||||||
|
Ok(v) => Ok(v),
|
||||||
|
Err(nix::Error::ECHILD) => {
|
||||||
|
info!("all child processes have exited, exiting...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error::Nix {
|
||||||
|
msg: "waitpid",
|
||||||
|
src: e,
|
||||||
|
}),
|
||||||
|
}?;
|
||||||
|
|
||||||
|
match status {
|
||||||
|
WaitStatus::Exited(pid, code) => {
|
||||||
|
if code != exitcode::OK {
|
||||||
|
exit_code = code;
|
||||||
|
}
|
||||||
|
debug!("child {} exited with code {}", pid, code);
|
||||||
|
}
|
||||||
|
WaitStatus::Signaled(pid, sig, _coredump) => {
|
||||||
|
debug!("child {} was terminated with signal {}", pid, sig);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(exit_code)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_pipes(names: Vec<&str>) -> Result<HashMap<String, PipePair>> {
|
fn create_pipes(names: Vec<&str>) -> Result<HashMap<String, PipePair>> {
|
||||||
|
15
src/main.rs
15
src/main.rs
@ -1,4 +1,4 @@
|
|||||||
use log::{error, info};
|
use log::error;
|
||||||
|
|
||||||
use clone_shim::{run, RunArgs};
|
use clone_shim::{run, RunArgs};
|
||||||
|
|
||||||
@ -34,6 +34,13 @@ fn main() {
|
|||||||
.help("Stop each spawned application process so that it can be attached to.")
|
.help("Stop each spawned application process so that it can be attached to.")
|
||||||
.takes_value(false),
|
.takes_value(false),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("daemon")
|
||||||
|
.long("daemon")
|
||||||
|
.short('D')
|
||||||
|
.help("Detach the shim from all child processes and exit immediately.")
|
||||||
|
.takes_value(false),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("binary")
|
Arg::new("binary")
|
||||||
.index(1)
|
.index(1)
|
||||||
@ -69,15 +76,13 @@ fn main() {
|
|||||||
let args = RunArgs {
|
let args = RunArgs {
|
||||||
spec: matches.value_of("spec").map(Path::new),
|
spec: matches.value_of("spec").map(Path::new),
|
||||||
debug: matches.is_present("debug"),
|
debug: matches.is_present("debug"),
|
||||||
|
daemon: matches.is_present("daemon"),
|
||||||
binary,
|
binary,
|
||||||
binary_args,
|
binary_args,
|
||||||
};
|
};
|
||||||
|
|
||||||
match run(&args) {
|
match run(&args) {
|
||||||
Ok(_) => {
|
Ok(_) => exitcode::OK,
|
||||||
info!("launched successfully");
|
|
||||||
exitcode::OK
|
|
||||||
}
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("error: {}", e);
|
error!("error: {}", e);
|
||||||
-1
|
-1
|
||||||
|
Loading…
Reference in New Issue
Block a user