1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
pub(crate) mod clock; pub(crate) mod fd; pub(crate) mod osdir; pub(crate) mod osfile; pub(crate) mod osother; pub(crate) mod stdio; use cfg_if::cfg_if; cfg_if! { if #[cfg(unix)] { mod unix; use unix as sys_impl; pub use unix::preopen_dir; } else if #[cfg(windows)] { mod windows; use windows as sys_impl; pub use windows::preopen_dir; } else { compile_error!("wasi-common doesn't compile for this platform yet"); } } pub(crate) use sys_impl::path; pub(crate) use sys_impl::poll; use super::handle::Handle; use crate::wasi::types; use osdir::OsDir; use osfile::OsFile; use osother::OsOther; use std::convert::TryFrom; use std::fs::File; use std::io; use std::mem::ManuallyDrop; use stdio::{Stderr, Stdin, Stdout}; use sys_impl::get_file_type; pub(crate) trait AsFile { fn as_file(&self) -> io::Result<ManuallyDrop<File>>; } impl AsFile for dyn Handle + 'static { fn as_file(&self) -> io::Result<ManuallyDrop<File>> { if let Some(file) = self.as_any().downcast_ref::<OsFile>() { file.as_file() } else if let Some(dir) = self.as_any().downcast_ref::<OsDir>() { dir.as_file() } else if let Some(stdin) = self.as_any().downcast_ref::<Stdin>() { stdin.as_file() } else if let Some(stdout) = self.as_any().downcast_ref::<Stdout>() { stdout.as_file() } else if let Some(stderr) = self.as_any().downcast_ref::<Stderr>() { stderr.as_file() } else if let Some(other) = self.as_any().downcast_ref::<OsOther>() { other.as_file() } else { log::error!("tried to make std::fs::File from non-OS handle"); Err(io::Error::from_raw_os_error(libc::EBADF)) } } } impl TryFrom<File> for Box<dyn Handle> { type Error = io::Error; fn try_from(file: File) -> io::Result<Self> { let file_type = get_file_type(&file)?; match file_type { types::Filetype::RegularFile => { let handle = OsFile::try_from(file)?; log::debug!("Created new instance of OsFile: {:?}", handle); Ok(Box::new(handle)) } types::Filetype::Directory => { let handle = OsDir::try_from(file)?; log::debug!("Created new instance of OsDir: {:?}", handle); Ok(Box::new(handle)) } _ => { let handle = OsOther::try_from(file)?; log::debug!("Created new instance of OsOther: {:?}", handle); Ok(Box::new(handle)) } } } }