diff options
author | Profpatsch <mail@profpatsch.de> | 2021-02-05 10:24:20 +0100 |
---|---|---|
committer | Profpatsch <mail@profpatsch.de> | 2021-02-05 10:24:20 +0100 |
commit | 035f7e860957e8c5637bdd1c033c1953dce980b3 (patch) | |
tree | 71b076b536d6a6a8839a54c57debd6c3401cdb14 /pkgs/profpatsch/netencode | |
parent | 8faf9338c363df8cebae4089b8c4b1832b6cb251 (diff) |
pkgs/profpatsch: adjust exec stuff to new skalibs
skarnet thought it would be wise to completely change the skalibs exec function interface without any backwards compat, so here we are. Have to reverse the code a bit, because `xmexec0` is a recursive `#define` pointing to `xmexec0_af`. `record-get` gets a rust treatment, it doesn’t really need the C interface just to exec into prog.
Diffstat (limited to 'pkgs/profpatsch/netencode')
-rw-r--r-- | pkgs/profpatsch/netencode/default.nix | 3 | ||||
-rw-r--r-- | pkgs/profpatsch/netencode/record-get.rs | 42 |
2 files changed, 37 insertions, 8 deletions
diff --git a/pkgs/profpatsch/netencode/default.nix b/pkgs/profpatsch/netencode/default.nix index 8457e1f5..bafedc13 100644 --- a/pkgs/profpatsch/netencode/default.nix +++ b/pkgs/profpatsch/netencode/default.nix @@ -35,10 +35,9 @@ let netencode-rs = netencode-rs-common false; record-get = writeRustSimple "record-get" { - dependencies = [ netencode-rs el-semicolon el-exec ]; + dependencies = [ netencode-rs el-semicolon ]; # TODO: for some reason the skarnet linker flag # is propagated by the link target is not? - buildInputs = [ pkgs.skalibs ]; } ./record-get.rs; diff --git a/pkgs/profpatsch/netencode/record-get.rs b/pkgs/profpatsch/netencode/record-get.rs index c823249d..60d2b52d 100644 --- a/pkgs/profpatsch/netencode/record-get.rs +++ b/pkgs/profpatsch/netencode/record-get.rs @@ -1,10 +1,10 @@ extern crate netencode; extern crate el_semicolon; -extern crate el_exec; use std::io::Read; use std::ffi::{CString, OsStr}; use std::os::unix::ffi::{OsStringExt, OsStrExt}; +use std::os::unix::process::{CommandExt}; use el_semicolon::{el_semicolon, Arg}; use netencode::{U, encode}; use netencode::parse::{u_u}; @@ -43,11 +43,8 @@ fn main() { } } } - let mut p : Vec<CString> = vec![]; - for arg in prog { - p.push(CString::new(*arg).unwrap()); - } - el_exec::xpathexec0(&p); + let env: Vec<(&[u8], &[u8])> = vec![]; + exec_into_args("record-get", prog, env) }, Ok(_) => { eprintln!("not a record!"); @@ -61,3 +58,36 @@ fn main() { } } } + +pub fn exec_into_args<'a, 'b, Args, Arg, Env, Key, Val>(current_prog_name: &str, args: Args, env_additions: Env) -> ! +where + Args: IntoIterator<Item = Arg>, + Arg: AsRef<[u8]>, + Env: IntoIterator<Item = (Key, Val)>, + Key: AsRef<[u8]>, + Val: AsRef<[u8]>, +{ + // TODO: is this possible without collecting into a Vec first, just leaving it an IntoIterator? + let args = args.into_iter().collect::<Vec<Arg>>(); + let mut args = args.iter().map(|v| OsStr::from_bytes(v.as_ref())); + let prog = args.nth(0).expect(&format!("{}: first argument must be an executable", current_prog_name)); + // TODO: same here + let env = env_additions.into_iter().collect::<Vec<(Key, Val)>>(); + let env = env.iter().map(|(k,v)| (OsStr::from_bytes(k.as_ref()), OsStr::from_bytes(v.as_ref()))); + let err = std::process::Command::new(prog).args(args).envs(env).exec(); + die_missing_executable(current_prog_name, format!("exec failed: {:?}, while trying to execing into {:?}", err, prog)); +} + +/// Exit 127 to signify a missing executable. +pub fn die_missing_executable<S>(current_prog_name: &str, msg: S) -> ! +where S: AsRef<str> +{ + die_with(127, current_prog_name, msg) +} + +fn die_with<S>(status: i32, current_prog_name: &str, msg: S) -> ! +where S: AsRef<str> +{ + eprintln!("{}: {}", current_prog_name, msg.as_ref()); + std::process::exit(status) +} |