#![deny(clippy::pedantic)]
use std::{
ffi::{CString, OsStr, OsString},
os::unix::prelude::{OsStrExt, OsStringExt},
};
use clap::Parser;
#[derive(Debug, Parser)]
#[clap(
about = "grim-reaper is a Linux-only wrapper program to cleanly sigkill its inner deep \
process tree."
)]
struct GrimReaper {
#[arg(value_parser = CStringValueParser)]
program: CString,
#[arg(allow_hyphen_values = true)]
#[arg(value_parser = CStringValueParser)]
args: Vec<CString>,
}
#[derive(Clone)]
struct CStringValueParser;
impl clap::builder::TypedValueParser for CStringValueParser {
type Value = CString;
fn parse_ref(
&self,
_cmd: &clap::Command,
_arg: Option<&clap::Arg>,
value: &OsStr,
) -> Result<Self::Value, clap::Error> {
CString::new(value.as_bytes().to_owned())
.map_err(|err| clap::Error::raw(clap::error::ErrorKind::ValueValidation, err))
}
fn parse(
&self,
_cmd: &clap::Command,
_arg: Option<&clap::Arg>,
value: OsString,
) -> Result<Self::Value, clap::Error> {
CString::new(value.into_vec())
.map_err(|err| clap::Error::raw(clap::error::ErrorKind::ValueValidation, err))
}
}
fn main() -> anyhow::Result<()> {
pretty_env_logger::init();
let opt = GrimReaper::parse();
lib_grim_reaper::exec_reaper(&opt.program, &opt.args)
}