about summary refs log tree commit diff
path: root/pkgs/profpatsch/netencode
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2021-02-05 10:24:20 +0100
committerProfpatsch <mail@profpatsch.de>2021-02-05 10:24:20 +0100
commit035f7e860957e8c5637bdd1c033c1953dce980b3 (patch)
tree71b076b536d6a6a8839a54c57debd6c3401cdb14 /pkgs/profpatsch/netencode
parent8faf9338c363df8cebae4089b8c4b1832b6cb251 (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.nix3
-rw-r--r--pkgs/profpatsch/netencode/record-get.rs42
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)
+}