From e530a582afe6a2b5735fd7cdf5e2e88391e58669 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 21 May 2019 22:59:56 +0200 Subject: [PATCH] Fix preopening dirs on Windows --- Cargo.toml | 3 +++ src/wasmtime.rs | 31 +++++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5731d55c56..90202005d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,9 @@ errno = "0.2.4" [target.'cfg(unix)'.dependencies] wasmtime-wasi-c = { path = "wasmtime-wasi-c" } +[target.'cfg(windows)'.dependencies] +winapi = "0.3" + [workspace] [features] diff --git a/src/wasmtime.rs b/src/wasmtime.rs index e2730a9956..3994da6059 100644 --- a/src/wasmtime.rs +++ b/src/wasmtime.rs @@ -118,11 +118,38 @@ fn read_wasm(path: PathBuf) -> Result, String> { }) } +fn preopen_dir>(path: P) -> io::Result { + #[cfg(windows)] + { + use std::fs::OpenOptions; + use std::os::windows::fs::OpenOptionsExt; + use winapi::um::winbase::FILE_FLAG_BACKUP_SEMANTICS; + + // To open a directory using CreateFile2, specify the + // FILE_FLAG_BACKUP_SEMANTICS flag as part of dwFileFlags... + // cf. https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfile2 + OpenOptions::new() + .create(false) + .write(true) + .read(true) + .attributes(FILE_FLAG_BACKUP_SEMANTICS) + .open(path) + } + #[cfg(unix)] + { + File::open(path) + } + #[cfg(not(any(windows, unix)))] + { + unimplemented!("this OS is currently not supported by Wasmtime") + } +} + fn compute_preopen_dirs(flag_dir: &[String], flag_mapdir: &[String]) -> Vec<(String, File)> { let mut preopen_dirs = Vec::new(); for dir in flag_dir { - let preopen_dir = File::open(dir).unwrap_or_else(|err| { + let preopen_dir = preopen_dir(dir).unwrap_or_else(|err| { println!("error while pre-opening directory {}: {}", dir, err); exit(1); }); @@ -136,7 +163,7 @@ fn compute_preopen_dirs(flag_dir: &[String], flag_mapdir: &[String]) -> Vec<(Str exit(1); } let (key, value) = (parts[0], parts[1]); - let preopen_dir = File::open(value).unwrap_or_else(|err| { + let preopen_dir = preopen_dir(value).unwrap_or_else(|err| { println!("error while pre-opening directory {}: {}", value, err); exit(1); });