From dd9b437cd341c67f5143a1b6bec274c45145e942 Mon Sep 17 00:00:00 2001 From: Tw Date: Tue, 14 Sep 2021 19:41:26 +0800 Subject: [PATCH] fix(plugin): Set preopen directories properly Every plugin will have following two directories for its use: `./`: Plugin's own data should be saved here, every plugin will have its own directory. `/global/`: All plugins have access to this directory, Some shared data could be saved here. Signed-off-by: Tw --- zellij-server/src/wasm_vm.rs | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/zellij-server/src/wasm_vm.rs b/zellij-server/src/wasm_vm.rs index cda1142923..7475bf46d8 100644 --- a/zellij-server/src/wasm_vm.rs +++ b/zellij-server/src/wasm_vm.rs @@ -56,6 +56,7 @@ pub(crate) struct PluginEnv { pub subscriptions: Arc>>, // FIXME: Once permission system is ready, this could be removed pub _allow_exec_host_cmd: bool, + plugin_own_data_dir: PathBuf, } // Thread main -------------------------------------------------------------------------------------------------------- @@ -63,12 +64,15 @@ pub(crate) fn wasm_thread_main(bus: Bus, store: Store, data_d info!("Wasm main thread starts"); let mut plugin_id = 0; let mut plugin_map = HashMap::new(); + let plugin_dir = data_dir.join("plugins/"); + let plugin_global_data_dir = plugin_dir.join("data"); + fs::create_dir_all(plugin_global_data_dir.as_path()).unwrap(); + loop { let (event, mut err_ctx) = bus.recv().expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Plugin((&event).into())); match event { PluginInstruction::Load(pid_tx, path, tab_index, _allow_exec_host_cmd) => { - let plugin_dir = data_dir.join("plugins/"); let wasm_bytes = fs::read(&path) .or_else(|_| fs::read(&path.with_extension("wasm"))) .or_else(|_| fs::read(&plugin_dir.join(&path).with_extension("wasm"))) @@ -83,15 +87,15 @@ pub(crate) fn wasm_thread_main(bus: Bus, store: Store, data_d path.as_path().file_name().unwrap().to_str().unwrap(), plugin_id, ); + + let plugin_name = path.as_path().file_stem().unwrap(); + let plugin_own_data_dir = plugin_global_data_dir.join(plugin_name); + let mut wasi_env = WasiState::new("Zellij") .env("CLICOLOR_FORCE", "1") - .preopen(|p| { - p.directory(".") // FIXME: Change this to a more meaningful dir - .alias(".") - .read(true) - .write(true) - .create(true) - }) + .map_dir("/host", ".") + .unwrap() + .map_dir("/data", plugin_own_data_dir.as_path()) .unwrap() .stdin(Box::new(input)) .stdout(Box::new(output)) @@ -112,6 +116,7 @@ pub(crate) fn wasm_thread_main(bus: Bus, store: Store, data_d wasi_env, subscriptions: Arc::new(Mutex::new(HashSet::new())), _allow_exec_host_cmd, + plugin_own_data_dir, }; let zellij = zellij_exports(&store, &plugin_env); @@ -154,10 +159,16 @@ pub(crate) fn wasm_thread_main(bus: Bus, store: Store, data_d buf_tx.send(wasi_read_string(&plugin_env.wasi_env)).unwrap(); } } - PluginInstruction::Unload(pid) => drop(plugin_map.remove(&pid)), + PluginInstruction::Unload(pid) => { + info!("Bye from plugin {}", &pid); + // TODO: remove plugin's own data directory + drop(plugin_map.remove(&pid)); + } PluginInstruction::Exit => break, } } + info!("wasm main thread exits"); + fs::remove_dir_all(plugin_global_data_dir.as_path()).unwrap(); } // Plugin API ---------------------------------------------------------------------------------------------------------