about summary refs log tree commit diff
path: root/pkgs/profpatsch/execline/el_exec.rs
blob: 25fad36f8b574286c517e35344a2c685b045d4dd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
        );
    }
}