Skip to main content

libinject/
cli.rs

1use crate::ffi;
2use crate::utils::Boolean;
3use navigator::cli::LibinjectArgs;
4use spin::Mutex;
5use std::ffi::CStr;
6use std::os::raw::c_char;
7use std::sync::LazyLock;
8
9static ARGS: LazyLock<Mutex<Option<LibinjectArgs>>> = LazyLock::new(|| Mutex::new(None));
10
11pub unsafe fn parse(client_id: ffi::client_id_t) -> LibinjectArgs {
12    unsafe {
13        let args_str = get_option_array(client_id)
14            .expect("Failed reading cli argument array")
15            .expect("Expecting at least one cli arg");
16        let parsed_args = LibinjectArgs::from_vec(args_str);
17        let mut args = ARGS.lock();
18        *args = Some(parsed_args.clone());
19        parsed_args
20    }
21}
22
23pub fn get_args() -> Result<LibinjectArgs, String> {
24    let args = ARGS.lock();
25    args.clone()
26        .ok_or("Args must be parsed first with cli::parse(client_id)".to_string())
27}
28
29pub unsafe fn get_option_array(client_id: ffi::client_id_t) -> Result<Option<Vec<String>>, String> {
30    unsafe {
31        let mut argc: i32 = 0;
32        let mut argv: *mut *const c_char = std::ptr::null_mut();
33
34        match ffi::dr_get_option_array(client_id, &mut argc, &mut argv).as_bool() {
35            true => {
36                if argc == 0 {
37                    return Ok(None);
38                }
39                if argv.is_null() {
40                    return Err(format!(
41                        "There were {argc} arguments, but the C pointer to the array was null!"
42                    ));
43                }
44
45                let slice = std::slice::from_raw_parts(argv, argc as usize);
46                let vec = slice
47                    .iter()
48                    .map(|&ptr| {
49                        // Convert C string to Rust String
50                        CStr::from_ptr(ptr).to_string_lossy().into_owned()
51                    })
52                    .collect();
53
54                Ok(Some(vec))
55            }
56            false => Err("Call to dr_get_option_array failed".to_string()),
57        }
58    }
59}