diff options
author | Profpatsch <mail@profpatsch.de> | 2020-06-28 15:14:04 +0200 |
---|---|---|
committer | Profpatsch <mail@profpatsch.de> | 2020-06-28 15:14:04 +0200 |
commit | 3f79ddf06375c3b34569c8b9ce91a607bbd0f052 (patch) | |
tree | c4e7515cb141cd9bce86df7e113056000af8f60d /pkgs/profpatsch/execline/el_exec.rs | |
parent | 13ad936f8432d2fe46169716ddf5eb7d4f84f202 (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.rs | 32 |
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 + ); + } +} |