about summary refs log tree commit diff
path: root/pkgs/profpatsch/execline/el_exec.rs
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2020-06-28 15:14:04 +0200
committerProfpatsch <mail@profpatsch.de>2020-06-28 15:14:04 +0200
commit3f79ddf06375c3b34569c8b9ce91a607bbd0f052 (patch)
treec4e7515cb141cd9bce86df7e113056000af8f60d /pkgs/profpatsch/execline/el_exec.rs
parent13ad936f8432d2fe46169716ddf5eb7d4f84f202 (diff)
pkgs/profpatsch/execline: add el_exec and el_substitute
el_exec: wraps the various execve wrappers in skalib that are useful
for writing execline-like utils. currently only `xpathexec0` is
supported, which execs into the argv you give it or errors with the
right error if file not found.

el_substitute: execline argv substitution! Wraps the execline
function, so it will behave exactly the same as the existing execline
utils, like `importas`.
Diffstat (limited to 'pkgs/profpatsch/execline/el_exec.rs')
-rw-r--r--pkgs/profpatsch/execline/el_exec.rs32
1 files changed, 32 insertions, 0 deletions
diff --git a/pkgs/profpatsch/execline/el_exec.rs b/pkgs/profpatsch/execline/el_exec.rs
new file mode 100644
index 00000000..25fad36f
--- /dev/null
+++ b/pkgs/profpatsch/execline/el_exec.rs
@@ -0,0 +1,32 @@
+use std::ffi::CStr;
+extern crate libc;
+
+fn to_c_argv<S: AsRef<CStr>>(s: &[S]) -> (&[S], Vec<*const libc::c_char>) {
+    let mut c_ptr_args = s.iter()
+        .map(|s| s.as_ref().as_ptr())
+        .collect::<Vec<*const libc::c_char>>();
+    c_ptr_args.push(std::ptr::null());
+    (s, c_ptr_args)
+}
+
+/// Exec into argv, or exit 0 if it’s empty.
+/// Will throw 127 if the executable is not found (ENOENT)
+/// and 126 for any other exec error.
+pub fn xpathexec0<'a, S: AsRef<CStr>>(argv: &'a [S]) {
+    let (c_strings, c_argv) = to_c_argv(argv);
+
+    unsafe {
+        C::xpathexec0(
+            c_argv.as_ptr() as *const *const libc::c_char
+        )
+    }
+}
+
+mod C {
+    #[link(name = "skarnet")]
+    extern "C" {
+        pub fn xpathexec0(
+            argv: *const *const libc::c_char
+        );
+    }
+}