sys: import types from handle or sched, not wasi. drop types:: prefix.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use crate::wasi::types;
|
||||
use crate::sched::{Clockid, Timestamp};
|
||||
use crate::{Error, Result};
|
||||
use cpu_time::{ProcessTime, ThreadTime};
|
||||
use lazy_static::lazy_static;
|
||||
@@ -12,7 +12,7 @@ lazy_static! {
|
||||
|
||||
// Timer resolution on Windows is really hard. We may consider exposing the resolution of the respective
|
||||
// timers as an associated function in the future.
|
||||
pub(crate) fn res_get(clock_id: types::Clockid) -> Result<types::Timestamp> {
|
||||
pub(crate) fn res_get(clock_id: Clockid) -> Result<Timestamp> {
|
||||
let ts = match clock_id {
|
||||
// This is the best that we can do with std::time::SystemTime.
|
||||
// Rust uses GetSystemTimeAsFileTime, which is said to have the resolution of
|
||||
@@ -47,25 +47,25 @@ pub(crate) fn res_get(clock_id: types::Clockid) -> Result<types::Timestamp> {
|
||||
// [4] https://www.codeproject.com/Tips/1011902/High-Resolution-Time-For-Windows
|
||||
// [5] https://stackoverflow.com/questions/7685762/windows-7-timing-functions-how-to-use-getsystemtimeadjustment-correctly
|
||||
// [6] https://bugs.python.org/issue19007
|
||||
types::Clockid::Realtime => 55_000_000,
|
||||
Clockid::Realtime => 55_000_000,
|
||||
// std::time::Instant uses QueryPerformanceCounter & QueryPerformanceFrequency internally
|
||||
types::Clockid::Monotonic => *PERF_COUNTER_RES,
|
||||
Clockid::Monotonic => *PERF_COUNTER_RES,
|
||||
// The best we can do is to hardcode the value from the docs.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes
|
||||
types::Clockid::ProcessCputimeId => 100,
|
||||
Clockid::ProcessCputimeId => 100,
|
||||
// The best we can do is to hardcode the value from the docs.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreadtimes
|
||||
types::Clockid::ThreadCputimeId => 100,
|
||||
Clockid::ThreadCputimeId => 100,
|
||||
};
|
||||
Ok(ts)
|
||||
}
|
||||
|
||||
pub(crate) fn time_get(clock_id: types::Clockid) -> Result<types::Timestamp> {
|
||||
pub(crate) fn time_get(clock_id: Clockid) -> Result<Timestamp> {
|
||||
let duration = match clock_id {
|
||||
types::Clockid::Realtime => get_monotonic_time(),
|
||||
types::Clockid::Monotonic => get_realtime_time()?,
|
||||
types::Clockid::ProcessCputimeId => get_proc_cputime()?,
|
||||
types::Clockid::ThreadCputimeId => get_thread_cputime()?,
|
||||
Clockid::Realtime => get_monotonic_time(),
|
||||
Clockid::Monotonic => get_realtime_time()?,
|
||||
Clockid::ProcessCputimeId => get_proc_cputime()?,
|
||||
Clockid::ThreadCputimeId => get_thread_cputime()?,
|
||||
};
|
||||
let duration = duration.as_nanos().try_into()?;
|
||||
Ok(duration)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use super::file_serial_no;
|
||||
use super::oshandle::RawOsHandle;
|
||||
use crate::handle::{Advice, Dircookie, Dirent, Fdflags, Filesize, Filestat};
|
||||
use crate::path;
|
||||
use crate::sys::osdir::OsDir;
|
||||
use crate::sys::osfile::OsFile;
|
||||
use crate::sys::AsFile;
|
||||
use crate::wasi::types;
|
||||
use crate::Result;
|
||||
use std::convert::TryInto;
|
||||
use std::fs::{File, OpenOptions};
|
||||
@@ -14,8 +14,8 @@ use std::path::Path;
|
||||
use tracing::trace;
|
||||
use winx::file::{AccessMode, FileModeInformation, Flags};
|
||||
|
||||
pub(crate) fn fdstat_get(file: &File) -> Result<types::Fdflags> {
|
||||
let mut fdflags = types::Fdflags::empty();
|
||||
pub(crate) fn fdstat_get(file: &File) -> Result<Fdflags> {
|
||||
let mut fdflags = Fdflags::empty();
|
||||
let handle = file.as_raw_handle();
|
||||
let access_mode = winx::file::query_access_information(handle)?;
|
||||
let mode = winx::file::query_mode_information(handle)?;
|
||||
@@ -24,13 +24,13 @@ pub(crate) fn fdstat_get(file: &File) -> Result<types::Fdflags> {
|
||||
if access_mode.contains(AccessMode::FILE_APPEND_DATA)
|
||||
&& !access_mode.contains(AccessMode::FILE_WRITE_DATA)
|
||||
{
|
||||
fdflags |= types::Fdflags::APPEND;
|
||||
fdflags |= Fdflags::APPEND;
|
||||
}
|
||||
|
||||
if mode.contains(FileModeInformation::FILE_WRITE_THROUGH) {
|
||||
// Only report __WASI_FDFLAGS_SYNC
|
||||
// This is technically the only one of the O_?SYNC flags Windows supports.
|
||||
fdflags |= types::Fdflags::SYNC;
|
||||
fdflags |= Fdflags::SYNC;
|
||||
}
|
||||
|
||||
// Files do not support the `__WASI_FDFLAGS_NONBLOCK` flag
|
||||
@@ -42,10 +42,7 @@ pub(crate) fn fdstat_get(file: &File) -> Result<types::Fdflags> {
|
||||
// handle came from `CreateFile`, but the Rust's libstd will use `GetStdHandle`
|
||||
// rather than `CreateFile`. Relevant discussion can be found in:
|
||||
// https://github.com/rust-lang/rust/issues/40490
|
||||
pub(crate) fn fdstat_set_flags(
|
||||
file: &File,
|
||||
fdflags: types::Fdflags,
|
||||
) -> Result<Option<RawOsHandle>> {
|
||||
pub(crate) fn fdstat_set_flags(file: &File, fdflags: Fdflags) -> Result<Option<RawOsHandle>> {
|
||||
let handle = file.as_raw_handle();
|
||||
let access_mode = winx::file::query_access_information(handle)?;
|
||||
let new_access_mode = file_access_mode_from_fdflags(
|
||||
@@ -65,14 +62,14 @@ pub(crate) fn fdstat_set_flags(
|
||||
|
||||
pub(crate) fn advise(
|
||||
_file: &OsFile,
|
||||
_advice: types::Advice,
|
||||
_offset: types::Filesize,
|
||||
_len: types::Filesize,
|
||||
_advice: Advice,
|
||||
_offset: Filesize,
|
||||
_len: Filesize,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn file_access_mode_from_fdflags(fdflags: types::Fdflags, read: bool, write: bool) -> AccessMode {
|
||||
fn file_access_mode_from_fdflags(fdflags: Fdflags, read: bool, write: bool) -> AccessMode {
|
||||
let mut access_mode = AccessMode::READ_CONTROL;
|
||||
|
||||
// Note that `GENERIC_READ` and `GENERIC_WRITE` cannot be used to properly support append-only mode
|
||||
@@ -89,7 +86,7 @@ fn file_access_mode_from_fdflags(fdflags: types::Fdflags, read: bool, write: boo
|
||||
// For append, grant the handle FILE_APPEND_DATA access but *not* FILE_WRITE_DATA.
|
||||
// This makes the handle "append only".
|
||||
// Changes to the file pointer will be ignored (like POSIX's O_APPEND behavior).
|
||||
if fdflags.contains(&types::Fdflags::APPEND) {
|
||||
if fdflags.contains(&Fdflags::APPEND) {
|
||||
access_mode.insert(AccessMode::FILE_APPEND_DATA);
|
||||
access_mode.remove(AccessMode::FILE_WRITE_DATA);
|
||||
}
|
||||
@@ -127,8 +124,8 @@ fn file_access_mode_from_fdflags(fdflags: types::Fdflags, read: bool, write: boo
|
||||
// other entries, in order they were returned by FindNextFileW get subsequent integers as their cookies
|
||||
pub(crate) fn readdir(
|
||||
dirfd: &OsDir,
|
||||
cookie: types::Dircookie,
|
||||
) -> Result<Box<dyn Iterator<Item = Result<(types::Dirent, String)>>>> {
|
||||
cookie: Dircookie,
|
||||
) -> Result<Box<dyn Iterator<Item = Result<(Dirent, String)>>>> {
|
||||
use winx::file::get_file_path;
|
||||
|
||||
let cookie = cookie.try_into()?;
|
||||
@@ -146,7 +143,7 @@ pub(crate) fn readdir(
|
||||
let ftype = dir.file_type()?;
|
||||
let name = path::from_host(dir.file_name())?;
|
||||
let d_ino = File::open(dir.path()).and_then(|f| file_serial_no(&f))?;
|
||||
let dirent = types::Dirent {
|
||||
let dirent = Dirent {
|
||||
d_namlen: name.len().try_into()?,
|
||||
d_type: ftype.into(),
|
||||
d_ino,
|
||||
@@ -171,8 +168,8 @@ pub(crate) fn readdir(
|
||||
fn dirent_from_path<P: AsRef<Path>>(
|
||||
path: P,
|
||||
name: &str,
|
||||
cookie: types::Dircookie,
|
||||
) -> Result<(types::Dirent, String)> {
|
||||
cookie: Dircookie,
|
||||
) -> Result<(Dirent, String)> {
|
||||
let path = path.as_ref();
|
||||
trace!("dirent_from_path: opening {}", path.to_string_lossy());
|
||||
|
||||
@@ -183,7 +180,7 @@ fn dirent_from_path<P: AsRef<Path>>(
|
||||
.open(path)?;
|
||||
let ty = file.metadata()?.file_type();
|
||||
let name = name.to_owned();
|
||||
let dirent = types::Dirent {
|
||||
let dirent = Dirent {
|
||||
d_namlen: name.len().try_into()?,
|
||||
d_next: cookie,
|
||||
d_type: ty.into(),
|
||||
@@ -192,7 +189,7 @@ fn dirent_from_path<P: AsRef<Path>>(
|
||||
Ok((dirent, name))
|
||||
}
|
||||
|
||||
pub(crate) fn filestat_get(file: &File) -> Result<types::Filestat> {
|
||||
pub(crate) fn filestat_get(file: &File) -> Result<Filestat> {
|
||||
let filestat = file.try_into()?;
|
||||
Ok(filestat)
|
||||
}
|
||||
|
||||
@@ -8,9 +8,8 @@ pub(crate) mod path;
|
||||
pub(crate) mod poll;
|
||||
pub(crate) mod stdio;
|
||||
|
||||
use crate::handle::HandleRights;
|
||||
use crate::handle::{Fdflags, Filestat, Filetype, HandleRights, Oflags, Rights, RightsExt};
|
||||
use crate::sys::AsFile;
|
||||
use crate::wasi::{types, RightsExt};
|
||||
use crate::{Error, Result};
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::fs::File;
|
||||
@@ -28,54 +27,50 @@ impl<T: AsRawHandle> AsFile for T {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_file_type(file: &File) -> io::Result<types::Filetype> {
|
||||
pub(super) fn get_file_type(file: &File) -> io::Result<Filetype> {
|
||||
let file_type = unsafe { winx::file::get_file_type(file.as_raw_handle())? };
|
||||
let file_type = if file_type.is_char() {
|
||||
// character file: LPT device or console
|
||||
// TODO: rule out LPT device
|
||||
types::Filetype::CharacterDevice
|
||||
Filetype::CharacterDevice
|
||||
} else if file_type.is_disk() {
|
||||
// disk file: file, dir or disk device
|
||||
let meta = file.metadata()?;
|
||||
if meta.is_dir() {
|
||||
types::Filetype::Directory
|
||||
Filetype::Directory
|
||||
} else if meta.is_file() {
|
||||
types::Filetype::RegularFile
|
||||
Filetype::RegularFile
|
||||
} else {
|
||||
return Err(io::Error::from_raw_os_error(libc::EINVAL));
|
||||
}
|
||||
} else if file_type.is_pipe() {
|
||||
// pipe object: socket, named pipe or anonymous pipe
|
||||
// TODO: what about pipes, etc?
|
||||
types::Filetype::SocketStream
|
||||
Filetype::SocketStream
|
||||
} else {
|
||||
return Err(io::Error::from_raw_os_error(libc::EINVAL));
|
||||
};
|
||||
Ok(file_type)
|
||||
}
|
||||
|
||||
pub(super) fn get_rights(file_type: &types::Filetype) -> io::Result<HandleRights> {
|
||||
pub(super) fn get_rights(file_type: &Filetype) -> io::Result<HandleRights> {
|
||||
let (base, inheriting) = match file_type {
|
||||
types::Filetype::BlockDevice => (
|
||||
types::Rights::block_device_base(),
|
||||
types::Rights::block_device_inheriting(),
|
||||
Filetype::BlockDevice => (
|
||||
Rights::block_device_base(),
|
||||
Rights::block_device_inheriting(),
|
||||
),
|
||||
types::Filetype::CharacterDevice => (types::Rights::tty_base(), types::Rights::tty_base()),
|
||||
types::Filetype::SocketDgram | types::Filetype::SocketStream => (
|
||||
types::Rights::socket_base(),
|
||||
types::Rights::socket_inheriting(),
|
||||
Filetype::CharacterDevice => (Rights::tty_base(), Rights::tty_base()),
|
||||
Filetype::SocketDgram | Filetype::SocketStream => {
|
||||
(Rights::socket_base(), Rights::socket_inheriting())
|
||||
}
|
||||
Filetype::SymbolicLink | Filetype::Unknown => (
|
||||
Rights::regular_file_base(),
|
||||
Rights::regular_file_inheriting(),
|
||||
),
|
||||
types::Filetype::SymbolicLink | types::Filetype::Unknown => (
|
||||
types::Rights::regular_file_base(),
|
||||
types::Rights::regular_file_inheriting(),
|
||||
),
|
||||
types::Filetype::Directory => (
|
||||
types::Rights::directory_base(),
|
||||
types::Rights::directory_inheriting(),
|
||||
),
|
||||
types::Filetype::RegularFile => (
|
||||
types::Rights::regular_file_base(),
|
||||
types::Rights::regular_file_inheriting(),
|
||||
Filetype::Directory => (Rights::directory_base(), Rights::directory_inheriting()),
|
||||
Filetype::RegularFile => (
|
||||
Rights::regular_file_base(),
|
||||
Rights::regular_file_inheriting(),
|
||||
),
|
||||
};
|
||||
let rights = HandleRights::new(base, inheriting);
|
||||
@@ -132,12 +127,12 @@ fn systemtime_to_timestamp(st: SystemTime) -> Result<u64> {
|
||||
.map_err(Into::into) // u128 doesn't fit into u64
|
||||
}
|
||||
|
||||
impl TryFrom<&File> for types::Filestat {
|
||||
impl TryFrom<&File> for Filestat {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(file: &File) -> Result<Self> {
|
||||
let metadata = file.metadata()?;
|
||||
Ok(types::Filestat {
|
||||
Ok(Filestat {
|
||||
dev: device_id(file)?,
|
||||
ino: file_serial_no(file)?,
|
||||
nlink: num_hardlinks(file)?.try_into()?, // u64 doesn't fit into u32
|
||||
@@ -150,15 +145,15 @@ impl TryFrom<&File> for types::Filestat {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<types::Oflags> for CreationDisposition {
|
||||
fn from(oflags: types::Oflags) -> Self {
|
||||
if oflags.contains(&types::Oflags::CREAT) {
|
||||
if oflags.contains(&types::Oflags::EXCL) {
|
||||
impl From<Oflags> for CreationDisposition {
|
||||
fn from(oflags: Oflags) -> Self {
|
||||
if oflags.contains(&Oflags::CREAT) {
|
||||
if oflags.contains(&Oflags::EXCL) {
|
||||
CreationDisposition::CREATE_NEW
|
||||
} else {
|
||||
CreationDisposition::CREATE_ALWAYS
|
||||
}
|
||||
} else if oflags.contains(&types::Oflags::TRUNC) {
|
||||
} else if oflags.contains(&Oflags::TRUNC) {
|
||||
CreationDisposition::TRUNCATE_EXISTING
|
||||
} else {
|
||||
CreationDisposition::OPEN_EXISTING
|
||||
@@ -166,8 +161,8 @@ impl From<types::Oflags> for CreationDisposition {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<types::Fdflags> for Flags {
|
||||
fn from(fdflags: types::Fdflags) -> Self {
|
||||
impl From<Fdflags> for Flags {
|
||||
fn from(fdflags: Fdflags) -> Self {
|
||||
// Enable backup semantics so directories can be opened as files
|
||||
let mut flags = Flags::FILE_FLAG_BACKUP_SEMANTICS;
|
||||
|
||||
@@ -176,9 +171,9 @@ impl From<types::Fdflags> for Flags {
|
||||
// treat I/O operations on files as synchronous. WASI might have an async-io API in the future.
|
||||
|
||||
// Technically, Windows only supports __WASI_FDFLAGS_SYNC, but treat all the flags as the same.
|
||||
if fdflags.contains(&types::Fdflags::DSYNC)
|
||||
|| fdflags.contains(&types::Fdflags::RSYNC)
|
||||
|| fdflags.contains(&types::Fdflags::SYNC)
|
||||
if fdflags.contains(&Fdflags::DSYNC)
|
||||
|| fdflags.contains(&Fdflags::RSYNC)
|
||||
|| fdflags.contains(&Fdflags::SYNC)
|
||||
{
|
||||
flags.insert(Flags::FILE_FLAG_WRITE_THROUGH);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::oshandle::RawOsHandle;
|
||||
use crate::handle::HandleRights;
|
||||
use crate::wasi::{types, RightsExt};
|
||||
use crate::handle::{HandleRights, Rights, RightsExt};
|
||||
use std::cell::Cell;
|
||||
use std::convert::TryFrom;
|
||||
use std::fs::File;
|
||||
@@ -55,16 +54,13 @@ impl TryFrom<File> for OsDir {
|
||||
|
||||
fn get_rights(file: &File) -> io::Result<HandleRights> {
|
||||
use winx::file::{query_access_information, AccessMode};
|
||||
let mut rights = HandleRights::new(
|
||||
types::Rights::directory_base(),
|
||||
types::Rights::directory_inheriting(),
|
||||
);
|
||||
let mut rights = HandleRights::new(Rights::directory_base(), Rights::directory_inheriting());
|
||||
let mode = query_access_information(file.as_raw_handle())?;
|
||||
if mode.contains(AccessMode::FILE_GENERIC_READ) {
|
||||
rights.base |= types::Rights::FD_READ;
|
||||
rights.base |= Rights::FD_READ;
|
||||
}
|
||||
if mode.contains(AccessMode::FILE_GENERIC_WRITE) {
|
||||
rights.base |= types::Rights::FD_WRITE;
|
||||
rights.base |= Rights::FD_WRITE;
|
||||
}
|
||||
Ok(rights)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use super::oshandle::RawOsHandle;
|
||||
use crate::handle::HandleRights;
|
||||
use crate::handle::{HandleRights, Rights, RightsExt};
|
||||
use crate::sys::osfile::OsFile;
|
||||
use crate::wasi::{types, RightsExt};
|
||||
use std::convert::TryFrom;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@@ -24,15 +23,15 @@ impl TryFrom<File> for OsFile {
|
||||
fn get_rights(file: &File) -> io::Result<HandleRights> {
|
||||
use winx::file::{query_access_information, AccessMode};
|
||||
let mut rights = HandleRights::new(
|
||||
types::Rights::regular_file_base(),
|
||||
types::Rights::regular_file_inheriting(),
|
||||
Rights::regular_file_base(),
|
||||
Rights::regular_file_inheriting(),
|
||||
);
|
||||
let mode = query_access_information(file.as_raw_handle())?;
|
||||
if mode.contains(AccessMode::FILE_GENERIC_READ) {
|
||||
rights.base |= types::Rights::FD_READ;
|
||||
rights.base |= Rights::FD_READ;
|
||||
}
|
||||
if mode.contains(AccessMode::FILE_GENERIC_WRITE) {
|
||||
rights.base |= types::Rights::FD_WRITE;
|
||||
rights.base |= Rights::FD_WRITE;
|
||||
}
|
||||
Ok(rights)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::oshandle::RawOsHandle;
|
||||
use super::{get_file_type, get_rights};
|
||||
use crate::handle::Filetype;
|
||||
use crate::sys::osother::OsOther;
|
||||
use crate::wasi::types;
|
||||
use std::convert::TryFrom;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
@@ -12,7 +12,7 @@ impl TryFrom<File> for OsOther {
|
||||
|
||||
fn try_from(file: File) -> io::Result<Self> {
|
||||
let file_type = get_file_type(&file)?;
|
||||
if file_type == types::Filetype::RegularFile || file_type == types::Filetype::Directory {
|
||||
if file_type == Filetype::RegularFile || file_type == Filetype::Directory {
|
||||
return Err(io::Error::from_raw_os_error(libc::EINVAL));
|
||||
}
|
||||
let rights = get_rights(&file_type)?;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::handle::{Handle, HandleRights};
|
||||
use crate::handle::{Fdflags, Filestat, Fstflags, Handle, HandleRights, Oflags, Rights};
|
||||
use crate::sched::Timestamp;
|
||||
use crate::sys::osdir::OsDir;
|
||||
use crate::sys::{fd, AsFile};
|
||||
use crate::wasi::types;
|
||||
use crate::{Error, Result};
|
||||
use std::convert::TryFrom;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
@@ -52,7 +52,7 @@ fn concatenate<P: AsRef<Path>>(file: &OsDir, path: P) -> Result<PathBuf> {
|
||||
Ok(out_path)
|
||||
}
|
||||
|
||||
fn file_access_mode_from_fdflags(fdflags: types::Fdflags, read: bool, write: bool) -> AccessMode {
|
||||
fn file_access_mode_from_fdflags(fdflags: Fdflags, read: bool, write: bool) -> AccessMode {
|
||||
let mut access_mode = AccessMode::READ_CONTROL;
|
||||
|
||||
// We always need `FILE_WRITE_ATTRIBUTES` so that we can set attributes such as filetimes, etc.
|
||||
@@ -72,7 +72,7 @@ fn file_access_mode_from_fdflags(fdflags: types::Fdflags, read: bool, write: boo
|
||||
// For append, grant the handle FILE_APPEND_DATA access but *not* FILE_WRITE_DATA.
|
||||
// This makes the handle "append only".
|
||||
// Changes to the file pointer will be ignored (like POSIX's O_APPEND behavior).
|
||||
if fdflags.contains(&types::Fdflags::APPEND) {
|
||||
if fdflags.contains(&Fdflags::APPEND) {
|
||||
access_mode.insert(AccessMode::FILE_APPEND_DATA);
|
||||
access_mode.remove(AccessMode::FILE_WRITE_DATA);
|
||||
}
|
||||
@@ -92,27 +92,27 @@ pub(crate) fn from_host<S: AsRef<OsStr>>(s: S) -> Result<String> {
|
||||
|
||||
pub(crate) fn open_rights(
|
||||
input_rights: &HandleRights,
|
||||
oflags: types::Oflags,
|
||||
fdflags: types::Fdflags,
|
||||
oflags: Oflags,
|
||||
fdflags: Fdflags,
|
||||
) -> HandleRights {
|
||||
// which rights are needed on the dirfd?
|
||||
let mut needed_base = types::Rights::PATH_OPEN;
|
||||
let mut needed_base = Rights::PATH_OPEN;
|
||||
let mut needed_inheriting = input_rights.base | input_rights.inheriting;
|
||||
|
||||
// convert open flags
|
||||
if oflags.contains(&types::Oflags::CREAT) {
|
||||
needed_base |= types::Rights::PATH_CREATE_FILE;
|
||||
} else if oflags.contains(&types::Oflags::TRUNC) {
|
||||
needed_base |= types::Rights::PATH_FILESTAT_SET_SIZE;
|
||||
if oflags.contains(&Oflags::CREAT) {
|
||||
needed_base |= Rights::PATH_CREATE_FILE;
|
||||
} else if oflags.contains(&Oflags::TRUNC) {
|
||||
needed_base |= Rights::PATH_FILESTAT_SET_SIZE;
|
||||
}
|
||||
|
||||
// convert file descriptor flags
|
||||
if fdflags.contains(&types::Fdflags::DSYNC)
|
||||
|| fdflags.contains(&types::Fdflags::RSYNC)
|
||||
|| fdflags.contains(&types::Fdflags::SYNC)
|
||||
if fdflags.contains(&Fdflags::DSYNC)
|
||||
|| fdflags.contains(&Fdflags::RSYNC)
|
||||
|| fdflags.contains(&Fdflags::SYNC)
|
||||
{
|
||||
needed_inheriting |= types::Rights::FD_DATASYNC;
|
||||
needed_inheriting |= types::Rights::FD_SYNC;
|
||||
needed_inheriting |= Rights::FD_DATASYNC;
|
||||
needed_inheriting |= Rights::FD_SYNC;
|
||||
}
|
||||
|
||||
HandleRights::new(needed_base, needed_inheriting)
|
||||
@@ -206,18 +206,18 @@ pub(crate) fn open(
|
||||
path: &str,
|
||||
read: bool,
|
||||
write: bool,
|
||||
oflags: types::Oflags,
|
||||
fdflags: types::Fdflags,
|
||||
oflags: Oflags,
|
||||
fdflags: Fdflags,
|
||||
) -> Result<Box<dyn Handle>> {
|
||||
use winx::file::{AccessMode, CreationDisposition, Flags};
|
||||
|
||||
let is_trunc = oflags.contains(&types::Oflags::TRUNC);
|
||||
let is_trunc = oflags.contains(&Oflags::TRUNC);
|
||||
|
||||
if is_trunc {
|
||||
// Windows does not support append mode when opening for truncation
|
||||
// This is because truncation requires `GENERIC_WRITE` access, which will override the removal
|
||||
// of the `FILE_WRITE_DATA` permission.
|
||||
if fdflags.contains(&types::Fdflags::APPEND) {
|
||||
if fdflags.contains(&Fdflags::APPEND) {
|
||||
return Err(Error::Notsup);
|
||||
}
|
||||
}
|
||||
@@ -246,7 +246,7 @@ pub(crate) fn open(
|
||||
return Err(Error::Loop);
|
||||
}
|
||||
// check if we are trying to open a file as a dir
|
||||
if file_type.is_file() && oflags.contains(&types::Oflags::DIRECTORY) {
|
||||
if file_type.is_file() && oflags.contains(&Oflags::DIRECTORY) {
|
||||
return Err(Error::Notdir);
|
||||
}
|
||||
}
|
||||
@@ -499,7 +499,7 @@ pub(crate) fn remove_directory(dirfd: &OsDir, path: &str) -> Result<()> {
|
||||
std::fs::remove_dir(&path).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub(crate) fn filestat_get_at(dirfd: &OsDir, path: &str, follow: bool) -> Result<types::Filestat> {
|
||||
pub(crate) fn filestat_get_at(dirfd: &OsDir, path: &str, follow: bool) -> Result<Filestat> {
|
||||
use winx::file::Flags;
|
||||
let path = concatenate(dirfd, path)?;
|
||||
let mut opts = OpenOptions::new();
|
||||
@@ -517,9 +517,9 @@ pub(crate) fn filestat_get_at(dirfd: &OsDir, path: &str, follow: bool) -> Result
|
||||
pub(crate) fn filestat_set_times_at(
|
||||
dirfd: &OsDir,
|
||||
path: &str,
|
||||
atim: types::Timestamp,
|
||||
mtim: types::Timestamp,
|
||||
fst_flags: types::Fstflags,
|
||||
atim: Timestamp,
|
||||
mtim: Timestamp,
|
||||
fst_flags: Fstflags,
|
||||
follow: bool,
|
||||
) -> Result<()> {
|
||||
use winx::file::{AccessMode, Flags};
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use crate::handle::Handle;
|
||||
use crate::poll::{ClockEventData, FdEventData};
|
||||
use crate::handle::{Filetype, Handle};
|
||||
use crate::sched::{
|
||||
ClockEventData, Errno, Event, EventFdReadwrite, Eventrwflags, Eventtype, FdEventData,
|
||||
};
|
||||
use crate::sys::osdir::OsDir;
|
||||
use crate::sys::osfile::OsFile;
|
||||
use crate::sys::osother::OsOther;
|
||||
use crate::sys::stdio::{Stderr, Stdin, Stdout};
|
||||
use crate::sys::AsFile;
|
||||
use crate::wasi::types;
|
||||
use crate::{Error, Result};
|
||||
use lazy_static::lazy_static;
|
||||
use std::convert::TryInto;
|
||||
@@ -24,7 +25,7 @@ enum PollState {
|
||||
Ready,
|
||||
NotReady, // it's not ready, but we didn't wait
|
||||
TimedOut, // it's not ready and a timeout has occurred
|
||||
Error(types::Errno),
|
||||
Error(Errno),
|
||||
}
|
||||
|
||||
enum WaitMode {
|
||||
@@ -80,7 +81,7 @@ impl StdinPoll {
|
||||
// Linux returns `POLLIN` in both cases, and we imitate this behavior.
|
||||
let resp = match std::io::stdin().lock().fill_buf() {
|
||||
Ok(_) => PollState::Ready,
|
||||
Err(e) => PollState::Error(types::Errno::from(Error::from(e))),
|
||||
Err(e) => PollState::Error(Errno::from(Error::from(e))),
|
||||
};
|
||||
|
||||
// Notify the requestor about data in stdin. They may have already timed out,
|
||||
@@ -102,52 +103,45 @@ lazy_static! {
|
||||
};
|
||||
}
|
||||
|
||||
fn make_rw_event(
|
||||
event: &FdEventData,
|
||||
nbytes: std::result::Result<u64, types::Errno>,
|
||||
) -> types::Event {
|
||||
fn make_rw_event(event: &FdEventData, nbytes: std::result::Result<u64, Errno>) -> Event {
|
||||
let (nbytes, error) = match nbytes {
|
||||
Ok(nbytes) => (nbytes, types::Errno::Success),
|
||||
Ok(nbytes) => (nbytes, Errno::Success),
|
||||
Err(e) => (u64::default(), e),
|
||||
};
|
||||
types::Event {
|
||||
Event {
|
||||
userdata: event.userdata,
|
||||
type_: event.r#type,
|
||||
error,
|
||||
fd_readwrite: types::EventFdReadwrite {
|
||||
fd_readwrite: EventFdReadwrite {
|
||||
nbytes,
|
||||
flags: types::Eventrwflags::empty(),
|
||||
flags: Eventrwflags::empty(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn make_timeout_event(timeout: &ClockEventData) -> types::Event {
|
||||
types::Event {
|
||||
fn make_timeout_event(timeout: &ClockEventData) -> Event {
|
||||
Event {
|
||||
userdata: timeout.userdata,
|
||||
type_: types::Eventtype::Clock,
|
||||
error: types::Errno::Success,
|
||||
fd_readwrite: types::EventFdReadwrite {
|
||||
type_: Eventtype::Clock,
|
||||
error: Errno::Success,
|
||||
fd_readwrite: EventFdReadwrite {
|
||||
nbytes: 0,
|
||||
flags: types::Eventrwflags::empty(),
|
||||
flags: Eventrwflags::empty(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_timeout(
|
||||
timeout_event: ClockEventData,
|
||||
timeout: Duration,
|
||||
events: &mut Vec<types::Event>,
|
||||
) {
|
||||
fn handle_timeout(timeout_event: ClockEventData, timeout: Duration, events: &mut Vec<Event>) {
|
||||
thread::sleep(timeout);
|
||||
handle_timeout_event(timeout_event, events);
|
||||
}
|
||||
|
||||
fn handle_timeout_event(timeout_event: ClockEventData, events: &mut Vec<types::Event>) {
|
||||
fn handle_timeout_event(timeout_event: ClockEventData, events: &mut Vec<Event>) {
|
||||
let new_event = make_timeout_event(&timeout_event);
|
||||
events.push(new_event);
|
||||
}
|
||||
|
||||
fn handle_rw_event(event: FdEventData, out_events: &mut Vec<types::Event>) {
|
||||
fn handle_rw_event(event: FdEventData, out_events: &mut Vec<Event>) {
|
||||
let handle = &event.handle;
|
||||
let size = if let Some(_) = handle.as_any().downcast_ref::<Stdin>() {
|
||||
// We return the only universally correct lower bound, see the comment later in the function.
|
||||
@@ -159,12 +153,12 @@ fn handle_rw_event(event: FdEventData, out_events: &mut Vec<types::Event>) {
|
||||
// On Unix, ioctl(FIONREAD) will return 0 for stdout/stderr. Emulate the same behavior on Windows.
|
||||
Ok(0)
|
||||
} else {
|
||||
if event.r#type == types::Eventtype::FdRead {
|
||||
if event.r#type == Eventtype::FdRead {
|
||||
handle
|
||||
.as_file()
|
||||
.and_then(|f| f.metadata())
|
||||
.map(|m| m.len())
|
||||
.map_err(|ioerror| types::Errno::from(Error::from(ioerror)))
|
||||
.map_err(|ioerror| Errno::from(Error::from(ioerror)))
|
||||
} else {
|
||||
// The spec is unclear what nbytes should actually be for __WASI_EVENTTYPE_FD_WRITE and
|
||||
// the implementation on Unix just returns 0 here, so it's probably fine
|
||||
@@ -177,7 +171,7 @@ fn handle_rw_event(event: FdEventData, out_events: &mut Vec<types::Event>) {
|
||||
out_events.push(new_event);
|
||||
}
|
||||
|
||||
fn handle_error_event(event: FdEventData, error: types::Errno, out_events: &mut Vec<types::Event>) {
|
||||
fn handle_error_event(event: FdEventData, error: Errno, out_events: &mut Vec<Event>) {
|
||||
let new_event = make_rw_event(&event, Err(error));
|
||||
out_events.push(new_event);
|
||||
}
|
||||
@@ -185,7 +179,7 @@ fn handle_error_event(event: FdEventData, error: types::Errno, out_events: &mut
|
||||
pub(crate) fn oneoff(
|
||||
timeout: Option<ClockEventData>,
|
||||
fd_events: Vec<FdEventData>,
|
||||
events: &mut Vec<types::Event>,
|
||||
events: &mut Vec<Event>,
|
||||
) -> Result<()> {
|
||||
let timeout = timeout
|
||||
.map(|event| {
|
||||
@@ -234,7 +228,7 @@ pub(crate) fn oneoff(
|
||||
// considered immediately ready, following the behavior on Linux.
|
||||
immediate_events.push(event);
|
||||
} else if let Some(other) = handle.as_any().downcast_ref::<OsOther>() {
|
||||
if other.get_file_type() == types::Filetype::SocketStream {
|
||||
if other.get_file_type() == Filetype::SocketStream {
|
||||
// We map pipe to SocketStream
|
||||
pipe_events.push(event);
|
||||
} else {
|
||||
@@ -242,7 +236,7 @@ pub(crate) fn oneoff(
|
||||
"poll_oneoff: unsupported file type: {}",
|
||||
other.get_file_type()
|
||||
);
|
||||
handle_error_event(event, types::Errno::Notsup, events);
|
||||
handle_error_event(event, Errno::Notsup, events);
|
||||
}
|
||||
} else {
|
||||
tracing::error!("can poll FdEvent for OS resources only");
|
||||
|
||||
Reference in New Issue
Block a user