share state between hooks
Opened this issue · 0 comments
milahu commented
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;
}
}