Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

share state between hooks #24

Open
milahu opened this issue Sep 29, 2021 · 0 comments
Open

share state between hooks #24

milahu opened this issue Sep 29, 2021 · 0 comments

Comments

@milahu
Copy link

milahu commented Sep 29, 2021

could be useful. add to examples?

// we need Arc and Mutex to make this thread-safe
use std::sync::Arc;
use std::sync::Mutex;

use std::collections::HashMap;

struct State {
    map: HashMap<String, String>,
    init_done: bool,
    cwd: String
}

/* add to Cargo.toml:
lazy_static = "*"
*/
lazy_static::lazy_static! {
    static ref STATE_ARC: Arc<Mutex<State>> = {
        // init state. this is called on the first "lock state for this scope"
        let cwd_str = std::env::current_dir().unwrap().into_os_string().into_string().unwrap(); // pathbuf to string
        let state = State {
            map: HashMap::new(),
            init_done: false,
            cwd: cwd_str
        };
        let state_arc = Arc::new(Mutex::new(state));
        return state_arc;
    };
}


hook! {
    unsafe fn some_hooked_function(
        dir: *const libc::c_char
    ) -> libc::c_int => my_some_hooked_function {

        // lock state for this scope
        let mut state = STATE_ARC.lock().unwrap();

        // use state ...

        if !state.init_done {
            println!("preload init. cwd = {}", state.cwd);
            state.init_done = true;
        }

        let map_from = "foo";
        let map_to = "bar";
        state.map.insert(map_from.to_owned(), map_to.to_owned()); // must copy values

        for map_from in state.map.keys() {
            let map_to = state.map.get(map_from);
            println!("preload map {} -> {}", map_from, map_to);
        }
    }
}

hook! {
    unsafe fn chdir(
        dir: *const libc::c_char
    ) -> libc::c_int => my_chdir {
        let retval = real!(chdir)(dir);
        let dir_str = str_of_chars(dir);
        if retval == 0 {
            // success
            // lock state for this scope
            let mut state = STATE_ARC.lock().unwrap();
            if dir_str.starts_with("/") {
                state.cwd = dir_str.to_owned();
            }
            else {
                // get absolute path
                // TODO better: resolve ../
                let mut dir_abs = state.cwd.to_owned();
                dir_abs.push_str("/");
                dir_abs.push_str(dir_str);
                state.cwd = dir_abs;
            }
            println!("preload chdir {}", state.cwd);
        }
        return retval;
    }
}
@sladg sladg mentioned this issue Jan 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant