Initial error refactor
This commit is contained in:
committed by
Jakub Konka
parent
85a41d449c
commit
14aaffd46f
@@ -8,7 +8,7 @@ cfg_if! {
|
||||
pub use self::unix::preopen_dir;
|
||||
|
||||
pub(crate) fn errno_from_host(err: i32) -> host::__wasi_errno_t {
|
||||
host_impl::errno_from_nix(nix::errno::from_i32(err))
|
||||
host_impl::errno_from_nix(nix::errno::from_i32(err)).as_wasi_errno()
|
||||
}
|
||||
} else if #[cfg(windows)] {
|
||||
mod windows;
|
||||
@@ -23,7 +23,7 @@ cfg_if! {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn errno_from_ioerror(e: std::io::Error) -> host::__wasi_errno_t {
|
||||
pub(crate) fn errno_from_ioerror(e: &std::io::Error) -> host::__wasi_errno_t {
|
||||
match e.raw_os_error() {
|
||||
Some(code) => errno_from_host(code),
|
||||
None => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::fdentry::Descriptor;
|
||||
use crate::sys::{errno_from_host, errno_from_ioerror};
|
||||
use crate::{host, Result};
|
||||
use crate::{host, Error, Result};
|
||||
use std::io;
|
||||
use std::os::unix::prelude::{AsRawFd, FileTypeExt, FromRawFd, RawFd};
|
||||
|
||||
@@ -25,10 +24,7 @@ pub(crate) fn determine_type_and_access_rights<Fd: AsRawFd>(
|
||||
let (file_type, mut rights_base, rights_inheriting) = determine_type_rights(fd)?;
|
||||
|
||||
use nix::fcntl::{fcntl, OFlag, F_GETFL};
|
||||
let flags_bits = fcntl(fd.as_raw_fd(), F_GETFL).map_err(|err| {
|
||||
err.as_errno()
|
||||
.map_or(host::__WASI_EIO, |e| errno_from_host(e as i32))
|
||||
})?;
|
||||
let flags_bits = fcntl(fd.as_raw_fd(), F_GETFL)?;
|
||||
let flags = OFlag::from_bits_truncate(flags_bits);
|
||||
let accmode = flags & OFlag::O_ACCMODE;
|
||||
if accmode == OFlag::O_RDONLY {
|
||||
@@ -51,7 +47,7 @@ pub(crate) fn determine_type_rights<Fd: AsRawFd>(
|
||||
// we just make a `File` here for convenience; we don't want it to close when it drops
|
||||
let file =
|
||||
std::mem::ManuallyDrop::new(unsafe { std::fs::File::from_raw_fd(fd.as_raw_fd()) });
|
||||
let ft = file.metadata().map_err(errno_from_ioerror)?.file_type();
|
||||
let ft = file.metadata()?.file_type();
|
||||
if ft.is_block_device() {
|
||||
(
|
||||
host::__WASI_FILETYPE_BLOCK_DEVICE,
|
||||
@@ -59,10 +55,7 @@ pub(crate) fn determine_type_rights<Fd: AsRawFd>(
|
||||
host::RIGHTS_BLOCK_DEVICE_INHERITING,
|
||||
)
|
||||
} else if ft.is_char_device() {
|
||||
if nix::unistd::isatty(fd.as_raw_fd()).map_err(|err| {
|
||||
err.as_errno()
|
||||
.map_or(host::__WASI_EIO, |e| errno_from_host(e as i32))
|
||||
})? {
|
||||
if nix::unistd::isatty(fd.as_raw_fd())? {
|
||||
(
|
||||
host::__WASI_FILETYPE_CHARACTER_DEVICE,
|
||||
host::RIGHTS_TTY_BASE,
|
||||
@@ -89,10 +82,7 @@ pub(crate) fn determine_type_rights<Fd: AsRawFd>(
|
||||
)
|
||||
} else if ft.is_socket() {
|
||||
use nix::sys::socket;
|
||||
match socket::getsockopt(fd.as_raw_fd(), socket::sockopt::SockType).map_err(|err| {
|
||||
err.as_errno()
|
||||
.map_or(host::__WASI_EIO, |e| errno_from_host(e as i32))
|
||||
})? {
|
||||
match socket::getsockopt(fd.as_raw_fd(), socket::sockopt::SockType)? {
|
||||
socket::SockType::Datagram => (
|
||||
host::__WASI_FILETYPE_SOCKET_DGRAM,
|
||||
host::RIGHTS_SOCKET_BASE,
|
||||
@@ -103,7 +93,7 @@ pub(crate) fn determine_type_rights<Fd: AsRawFd>(
|
||||
host::RIGHTS_SOCKET_BASE,
|
||||
host::RIGHTS_SOCKET_INHERITING,
|
||||
),
|
||||
_ => return Err(host::__WASI_EINVAL),
|
||||
_ => return Err(Error::EINVAL),
|
||||
}
|
||||
} else if ft.is_fifo() {
|
||||
(
|
||||
@@ -112,7 +102,7 @@ pub(crate) fn determine_type_rights<Fd: AsRawFd>(
|
||||
host::RIGHTS_REGULAR_FILE_INHERITING,
|
||||
)
|
||||
} else {
|
||||
return Err(host::__WASI_EINVAL);
|
||||
return Err(Error::EINVAL);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,87 +2,91 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(dead_code)]
|
||||
use crate::{host, memory, Result};
|
||||
use crate::{host, memory, Error, Result};
|
||||
use log::warn;
|
||||
use std::ffi::OsStr;
|
||||
use std::os::unix::prelude::OsStrExt;
|
||||
|
||||
pub(crate) fn errno_from_nix(errno: nix::errno::Errno) -> host::__wasi_errno_t {
|
||||
pub(crate) fn errno_from_nix(errno: nix::errno::Errno) -> Error {
|
||||
match errno {
|
||||
nix::errno::Errno::EPERM => host::__WASI_EPERM,
|
||||
nix::errno::Errno::ENOENT => host::__WASI_ENOENT,
|
||||
nix::errno::Errno::ESRCH => host::__WASI_ESRCH,
|
||||
nix::errno::Errno::EINTR => host::__WASI_EINTR,
|
||||
nix::errno::Errno::EIO => host::__WASI_EIO,
|
||||
nix::errno::Errno::ENXIO => host::__WASI_ENXIO,
|
||||
nix::errno::Errno::E2BIG => host::__WASI_E2BIG,
|
||||
nix::errno::Errno::ENOEXEC => host::__WASI_ENOEXEC,
|
||||
nix::errno::Errno::EBADF => host::__WASI_EBADF,
|
||||
nix::errno::Errno::ECHILD => host::__WASI_ECHILD,
|
||||
nix::errno::Errno::EAGAIN => host::__WASI_EAGAIN,
|
||||
nix::errno::Errno::ENOMEM => host::__WASI_ENOMEM,
|
||||
nix::errno::Errno::EACCES => host::__WASI_EACCES,
|
||||
nix::errno::Errno::EFAULT => host::__WASI_EFAULT,
|
||||
nix::errno::Errno::EBUSY => host::__WASI_EBUSY,
|
||||
nix::errno::Errno::EEXIST => host::__WASI_EEXIST,
|
||||
nix::errno::Errno::EXDEV => host::__WASI_EXDEV,
|
||||
nix::errno::Errno::ENODEV => host::__WASI_ENODEV,
|
||||
nix::errno::Errno::ENOTDIR => host::__WASI_ENOTDIR,
|
||||
nix::errno::Errno::EISDIR => host::__WASI_EISDIR,
|
||||
nix::errno::Errno::EINVAL => host::__WASI_EINVAL,
|
||||
nix::errno::Errno::ENFILE => host::__WASI_ENFILE,
|
||||
nix::errno::Errno::EMFILE => host::__WASI_EMFILE,
|
||||
nix::errno::Errno::ENOTTY => host::__WASI_ENOTTY,
|
||||
nix::errno::Errno::ETXTBSY => host::__WASI_ETXTBSY,
|
||||
nix::errno::Errno::EFBIG => host::__WASI_EFBIG,
|
||||
nix::errno::Errno::ENOSPC => host::__WASI_ENOSPC,
|
||||
nix::errno::Errno::ESPIPE => host::__WASI_ESPIPE,
|
||||
nix::errno::Errno::EROFS => host::__WASI_EROFS,
|
||||
nix::errno::Errno::EMLINK => host::__WASI_EMLINK,
|
||||
nix::errno::Errno::EPIPE => host::__WASI_EPIPE,
|
||||
nix::errno::Errno::EDOM => host::__WASI_EDOM,
|
||||
nix::errno::Errno::ERANGE => host::__WASI_ERANGE,
|
||||
nix::errno::Errno::EDEADLK => host::__WASI_EDEADLK,
|
||||
nix::errno::Errno::ENAMETOOLONG => host::__WASI_ENAMETOOLONG,
|
||||
nix::errno::Errno::ENOLCK => host::__WASI_ENOLCK,
|
||||
nix::errno::Errno::ENOSYS => host::__WASI_ENOSYS,
|
||||
nix::errno::Errno::ENOTEMPTY => host::__WASI_ENOTEMPTY,
|
||||
nix::errno::Errno::ELOOP => host::__WASI_ELOOP,
|
||||
nix::errno::Errno::ENOMSG => host::__WASI_ENOMSG,
|
||||
nix::errno::Errno::EIDRM => host::__WASI_EIDRM,
|
||||
nix::errno::Errno::ENOLINK => host::__WASI_ENOLINK,
|
||||
nix::errno::Errno::EPROTO => host::__WASI_EPROTO,
|
||||
nix::errno::Errno::EMULTIHOP => host::__WASI_EMULTIHOP,
|
||||
nix::errno::Errno::EBADMSG => host::__WASI_EBADMSG,
|
||||
nix::errno::Errno::EOVERFLOW => host::__WASI_EOVERFLOW,
|
||||
nix::errno::Errno::EILSEQ => host::__WASI_EILSEQ,
|
||||
nix::errno::Errno::ENOTSOCK => host::__WASI_ENOTSOCK,
|
||||
nix::errno::Errno::EDESTADDRREQ => host::__WASI_EDESTADDRREQ,
|
||||
nix::errno::Errno::EMSGSIZE => host::__WASI_EMSGSIZE,
|
||||
nix::errno::Errno::EPROTOTYPE => host::__WASI_EPROTOTYPE,
|
||||
nix::errno::Errno::ENOPROTOOPT => host::__WASI_ENOPROTOOPT,
|
||||
nix::errno::Errno::EPROTONOSUPPORT => host::__WASI_EPROTONOSUPPORT,
|
||||
nix::errno::Errno::EAFNOSUPPORT => host::__WASI_EAFNOSUPPORT,
|
||||
nix::errno::Errno::EADDRINUSE => host::__WASI_EADDRINUSE,
|
||||
nix::errno::Errno::EADDRNOTAVAIL => host::__WASI_EADDRNOTAVAIL,
|
||||
nix::errno::Errno::ENETDOWN => host::__WASI_ENETDOWN,
|
||||
nix::errno::Errno::ENETUNREACH => host::__WASI_ENETUNREACH,
|
||||
nix::errno::Errno::ENETRESET => host::__WASI_ENETRESET,
|
||||
nix::errno::Errno::ECONNABORTED => host::__WASI_ECONNABORTED,
|
||||
nix::errno::Errno::ECONNRESET => host::__WASI_ECONNRESET,
|
||||
nix::errno::Errno::ENOBUFS => host::__WASI_ENOBUFS,
|
||||
nix::errno::Errno::EISCONN => host::__WASI_EISCONN,
|
||||
nix::errno::Errno::ENOTCONN => host::__WASI_ENOTCONN,
|
||||
nix::errno::Errno::ETIMEDOUT => host::__WASI_ETIMEDOUT,
|
||||
nix::errno::Errno::ECONNREFUSED => host::__WASI_ECONNREFUSED,
|
||||
nix::errno::Errno::EHOSTUNREACH => host::__WASI_EHOSTUNREACH,
|
||||
nix::errno::Errno::EALREADY => host::__WASI_EALREADY,
|
||||
nix::errno::Errno::EINPROGRESS => host::__WASI_EINPROGRESS,
|
||||
nix::errno::Errno::ESTALE => host::__WASI_ESTALE,
|
||||
nix::errno::Errno::EDQUOT => host::__WASI_EDQUOT,
|
||||
nix::errno::Errno::ECANCELED => host::__WASI_ECANCELED,
|
||||
nix::errno::Errno::EOWNERDEAD => host::__WASI_EOWNERDEAD,
|
||||
nix::errno::Errno::ENOTRECOVERABLE => host::__WASI_ENOTRECOVERABLE,
|
||||
_ => host::__WASI_ENOSYS,
|
||||
nix::errno::Errno::EPERM => Error::EPERM,
|
||||
nix::errno::Errno::ENOENT => Error::ENOENT,
|
||||
nix::errno::Errno::ESRCH => Error::ESRCH,
|
||||
nix::errno::Errno::EINTR => Error::EINTR,
|
||||
nix::errno::Errno::EIO => Error::EIO,
|
||||
nix::errno::Errno::ENXIO => Error::ENXIO,
|
||||
nix::errno::Errno::E2BIG => Error::E2BIG,
|
||||
nix::errno::Errno::ENOEXEC => Error::ENOEXEC,
|
||||
nix::errno::Errno::EBADF => Error::EBADF,
|
||||
nix::errno::Errno::ECHILD => Error::ECHILD,
|
||||
nix::errno::Errno::EAGAIN => Error::EAGAIN,
|
||||
nix::errno::Errno::ENOMEM => Error::ENOMEM,
|
||||
nix::errno::Errno::EACCES => Error::EACCES,
|
||||
nix::errno::Errno::EFAULT => Error::EFAULT,
|
||||
nix::errno::Errno::EBUSY => Error::EBUSY,
|
||||
nix::errno::Errno::EEXIST => Error::EEXIST,
|
||||
nix::errno::Errno::EXDEV => Error::EXDEV,
|
||||
nix::errno::Errno::ENODEV => Error::ENODEV,
|
||||
nix::errno::Errno::ENOTDIR => Error::ENOTDIR,
|
||||
nix::errno::Errno::EISDIR => Error::EISDIR,
|
||||
nix::errno::Errno::EINVAL => Error::EINVAL,
|
||||
nix::errno::Errno::ENFILE => Error::ENFILE,
|
||||
nix::errno::Errno::EMFILE => Error::EMFILE,
|
||||
nix::errno::Errno::ENOTTY => Error::ENOTTY,
|
||||
nix::errno::Errno::ETXTBSY => Error::ETXTBSY,
|
||||
nix::errno::Errno::EFBIG => Error::EFBIG,
|
||||
nix::errno::Errno::ENOSPC => Error::ENOSPC,
|
||||
nix::errno::Errno::ESPIPE => Error::ESPIPE,
|
||||
nix::errno::Errno::EROFS => Error::EROFS,
|
||||
nix::errno::Errno::EMLINK => Error::EMLINK,
|
||||
nix::errno::Errno::EPIPE => Error::EPIPE,
|
||||
nix::errno::Errno::EDOM => Error::EDOM,
|
||||
nix::errno::Errno::ERANGE => Error::ERANGE,
|
||||
nix::errno::Errno::EDEADLK => Error::EDEADLK,
|
||||
nix::errno::Errno::ENAMETOOLONG => Error::ENAMETOOLONG,
|
||||
nix::errno::Errno::ENOLCK => Error::ENOLCK,
|
||||
nix::errno::Errno::ENOSYS => Error::ENOSYS,
|
||||
nix::errno::Errno::ENOTEMPTY => Error::ENOTEMPTY,
|
||||
nix::errno::Errno::ELOOP => Error::ELOOP,
|
||||
nix::errno::Errno::ENOMSG => Error::ENOMSG,
|
||||
nix::errno::Errno::EIDRM => Error::EIDRM,
|
||||
nix::errno::Errno::ENOLINK => Error::ENOLINK,
|
||||
nix::errno::Errno::EPROTO => Error::EPROTO,
|
||||
nix::errno::Errno::EMULTIHOP => Error::EMULTIHOP,
|
||||
nix::errno::Errno::EBADMSG => Error::EBADMSG,
|
||||
nix::errno::Errno::EOVERFLOW => Error::EOVERFLOW,
|
||||
nix::errno::Errno::EILSEQ => Error::EILSEQ,
|
||||
nix::errno::Errno::ENOTSOCK => Error::ENOTSOCK,
|
||||
nix::errno::Errno::EDESTADDRREQ => Error::EDESTADDRREQ,
|
||||
nix::errno::Errno::EMSGSIZE => Error::EMSGSIZE,
|
||||
nix::errno::Errno::EPROTOTYPE => Error::EPROTOTYPE,
|
||||
nix::errno::Errno::ENOPROTOOPT => Error::ENOPROTOOPT,
|
||||
nix::errno::Errno::EPROTONOSUPPORT => Error::EPROTONOSUPPORT,
|
||||
nix::errno::Errno::EAFNOSUPPORT => Error::EAFNOSUPPORT,
|
||||
nix::errno::Errno::EADDRINUSE => Error::EADDRINUSE,
|
||||
nix::errno::Errno::EADDRNOTAVAIL => Error::EADDRNOTAVAIL,
|
||||
nix::errno::Errno::ENETDOWN => Error::ENETDOWN,
|
||||
nix::errno::Errno::ENETUNREACH => Error::ENETUNREACH,
|
||||
nix::errno::Errno::ENETRESET => Error::ENETRESET,
|
||||
nix::errno::Errno::ECONNABORTED => Error::ECONNABORTED,
|
||||
nix::errno::Errno::ECONNRESET => Error::ECONNRESET,
|
||||
nix::errno::Errno::ENOBUFS => Error::ENOBUFS,
|
||||
nix::errno::Errno::EISCONN => Error::EISCONN,
|
||||
nix::errno::Errno::ENOTCONN => Error::ENOTCONN,
|
||||
nix::errno::Errno::ETIMEDOUT => Error::ETIMEDOUT,
|
||||
nix::errno::Errno::ECONNREFUSED => Error::ECONNREFUSED,
|
||||
nix::errno::Errno::EHOSTUNREACH => Error::EHOSTUNREACH,
|
||||
nix::errno::Errno::EALREADY => Error::EALREADY,
|
||||
nix::errno::Errno::EINPROGRESS => Error::EINPROGRESS,
|
||||
nix::errno::Errno::ESTALE => Error::ESTALE,
|
||||
nix::errno::Errno::EDQUOT => Error::EDQUOT,
|
||||
nix::errno::Errno::ECANCELED => Error::ECANCELED,
|
||||
nix::errno::Errno::EOWNERDEAD => Error::EOWNERDEAD,
|
||||
nix::errno::Errno::ENOTRECOVERABLE => Error::ENOTRECOVERABLE,
|
||||
other => {
|
||||
warn!("Unknown error from nix: {}", other);
|
||||
Error::ENOSYS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,14 +183,12 @@ pub(crate) fn filestat_from_nix(
|
||||
fn filestat_to_timestamp(secs: u64, nsecs: u64) -> Result<host::__wasi_timestamp_t> {
|
||||
secs.checked_mul(1_000_000_000)
|
||||
.and_then(|sec_nsec| sec_nsec.checked_add(nsecs))
|
||||
.ok_or(host::__WASI_EOVERFLOW)
|
||||
.ok_or(Error::EOVERFLOW)
|
||||
}
|
||||
|
||||
let filetype = nix::sys::stat::SFlag::from_bits_truncate(filestat.st_mode);
|
||||
let dev =
|
||||
host::__wasi_device_t::try_from(filestat.st_dev).map_err(|_| host::__WASI_EOVERFLOW)?;
|
||||
let ino =
|
||||
host::__wasi_inode_t::try_from(filestat.st_ino).map_err(|_| host::__WASI_EOVERFLOW)?;
|
||||
let dev = host::__wasi_device_t::try_from(filestat.st_dev).map_err(|_| Error::EOVERFLOW)?;
|
||||
let ino = host::__wasi_inode_t::try_from(filestat.st_ino).map_err(|_| Error::EOVERFLOW)?;
|
||||
let st_atim = filestat_to_timestamp(filestat.st_atime as u64, filestat.st_atime_nsec as u64)?;
|
||||
let st_ctim = filestat_to_timestamp(filestat.st_ctime as u64, filestat.st_ctime_nsec as u64)?;
|
||||
let st_mtim = filestat_to_timestamp(filestat.st_mtime as u64, filestat.st_mtime_nsec as u64)?;
|
||||
@@ -222,7 +224,7 @@ pub(crate) fn dirent_filetype_from_host(
|
||||
Ok(host::__WASI_FILETYPE_UNKNOWN)
|
||||
}
|
||||
libc::DT_UNKNOWN => Ok(host::__WASI_FILETYPE_UNKNOWN),
|
||||
_ => Err(host::__WASI_EINVAL),
|
||||
_ => Err(Error::EINVAL),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +235,7 @@ pub(crate) fn dirent_from_host(host_entry: &nix::libc::dirent) -> Result<host::_
|
||||
.to_bytes()
|
||||
.len();
|
||||
if d_namlen > u32::max_value() as usize {
|
||||
return Err(host::__WASI_EIO);
|
||||
return Err(Error::EIO);
|
||||
}
|
||||
let d_type = dirent_filetype_from_host(host_entry)?;
|
||||
entry.d_ino = memory::enc_inode(host_entry.d_ino);
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
use super::fs_helpers::*;
|
||||
use crate::helpers::systemtime_to_timestamp;
|
||||
use crate::hostcalls_impl::PathGet;
|
||||
use crate::sys::errno_from_ioerror;
|
||||
use crate::sys::host_impl::{self, errno_from_nix};
|
||||
use crate::{host, Result};
|
||||
use crate::{host, Result, Error};
|
||||
use nix::libc::{self, c_long, c_void};
|
||||
use std::convert::TryInto;
|
||||
use std::ffi::CString;
|
||||
@@ -18,11 +17,11 @@ pub(crate) fn fd_pread(
|
||||
buf: &mut [u8],
|
||||
offset: host::__wasi_filesize_t,
|
||||
) -> Result<usize> {
|
||||
file.read_at(buf, offset).map_err(errno_from_ioerror)
|
||||
file.read_at(buf, offset).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub(crate) fn fd_pwrite(file: &File, buf: &[u8], offset: host::__wasi_filesize_t) -> Result<usize> {
|
||||
file.write_at(buf, offset).map_err(errno_from_ioerror)
|
||||
file.write_at(buf, offset).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub(crate) fn fd_fdstat_get(fd: &File) -> Result<host::__wasi_fdflags_t> {
|
||||
@@ -52,8 +51,8 @@ pub(crate) fn fd_advise(
|
||||
{
|
||||
use nix::fcntl::{posix_fadvise, PosixFadviseAdvice};
|
||||
|
||||
let offset = offset.try_into().map_err(|_| host::__WASI_EOVERFLOW)?;
|
||||
let len = len.try_into().map_err(|_| host::__WASI_EOVERFLOW)?;
|
||||
let offset = offset.try_into().map_err(|_| Error::EOVERFLOW)?;
|
||||
let len = len.try_into().map_err(|_| Error::EOVERFLOW)?;
|
||||
let host_advice = match advice {
|
||||
host::__WASI_ADVICE_DONTNEED => PosixFadviseAdvice::POSIX_FADV_DONTNEED,
|
||||
host::__WASI_ADVICE_SEQUENTIAL => PosixFadviseAdvice::POSIX_FADV_SEQUENTIAL,
|
||||
@@ -61,7 +60,7 @@ pub(crate) fn fd_advise(
|
||||
host::__WASI_ADVICE_NOREUSE => PosixFadviseAdvice::POSIX_FADV_NOREUSE,
|
||||
host::__WASI_ADVICE_RANDOM => PosixFadviseAdvice::POSIX_FADV_RANDOM,
|
||||
host::__WASI_ADVICE_NORMAL => PosixFadviseAdvice::POSIX_FADV_NORMAL,
|
||||
_ => return Err(host::__WASI_EINVAL),
|
||||
_ => return Err(Error::EINVAL),
|
||||
};
|
||||
|
||||
posix_fadvise(file.as_raw_fd(), offset, len, host_advice)
|
||||
@@ -85,7 +84,7 @@ pub(crate) fn fd_advise(
|
||||
| host::__WASI_ADVICE_NOREUSE
|
||||
| host::__WASI_ADVICE_RANDOM
|
||||
| host::__WASI_ADVICE_NORMAL => {}
|
||||
_ => return Err(host::__WASI_EINVAL),
|
||||
_ => return Err(Error::EINVAL),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -93,7 +92,7 @@ pub(crate) fn fd_advise(
|
||||
|
||||
pub(crate) fn path_create_directory(resolved: PathGet) -> Result<()> {
|
||||
use nix::libc::mkdirat;
|
||||
let path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| host::__WASI_EILSEQ)?;
|
||||
let path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
// nix doesn't expose mkdirat() yet
|
||||
match unsafe { mkdirat(resolved.dirfd().as_raw_fd(), path_cstr.as_ptr(), 0o777) } {
|
||||
0 => Ok(()),
|
||||
@@ -104,9 +103,9 @@ pub(crate) fn path_create_directory(resolved: PathGet) -> Result<()> {
|
||||
pub(crate) fn path_link(resolved_old: PathGet, resolved_new: PathGet) -> Result<()> {
|
||||
use nix::libc::linkat;
|
||||
let old_path_cstr =
|
||||
CString::new(resolved_old.path().as_bytes()).map_err(|_| host::__WASI_EILSEQ)?;
|
||||
CString::new(resolved_old.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let new_path_cstr =
|
||||
CString::new(resolved_new.path().as_bytes()).map_err(|_| host::__WASI_EILSEQ)?;
|
||||
CString::new(resolved_new.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
|
||||
// Not setting AT_SYMLINK_FOLLOW fails on most filesystems
|
||||
let atflags = libc::AT_SYMLINK_FOLLOW;
|
||||
@@ -174,12 +173,12 @@ pub(crate) fn path_open(
|
||||
AtFlags::AT_SYMLINK_NOFOLLOW,
|
||||
) {
|
||||
if SFlag::from_bits_truncate(stat.st_mode).contains(SFlag::S_IFSOCK) {
|
||||
return Err(host::__WASI_ENOTSUP);
|
||||
return Err(Error::ENOTSUP);
|
||||
} else {
|
||||
return Err(host::__WASI_ENXIO);
|
||||
return Err(Error::ENXIO);
|
||||
}
|
||||
} else {
|
||||
return Err(host::__WASI_ENXIO);
|
||||
return Err(Error::ENXIO);
|
||||
}
|
||||
}
|
||||
// Linux returns ENOTDIR instead of ELOOP when using O_NOFOLLOW|O_DIRECTORY
|
||||
@@ -193,18 +192,18 @@ pub(crate) fn path_open(
|
||||
AtFlags::AT_SYMLINK_NOFOLLOW,
|
||||
) {
|
||||
if SFlag::from_bits_truncate(stat.st_mode).contains(SFlag::S_IFLNK) {
|
||||
return Err(host::__WASI_ELOOP);
|
||||
return Err(Error::ELOOP);
|
||||
}
|
||||
}
|
||||
return Err(host::__WASI_ENOTDIR);
|
||||
return Err(Error::ENOTDIR);
|
||||
}
|
||||
// FreeBSD returns EMLINK instead of ELOOP when using O_NOFOLLOW on
|
||||
// a symlink.
|
||||
Some(Errno::EMLINK) if !(nix_all_oflags & OFlag::O_NOFOLLOW).is_empty() => {
|
||||
return Err(host::__WASI_ELOOP);
|
||||
return Err(Error::ELOOP);
|
||||
}
|
||||
Some(e) => return Err(host_impl::errno_from_nix(e)),
|
||||
None => return Err(host::__WASI_ENOSYS),
|
||||
None => return Err(Error::ENOSYS),
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -275,7 +274,7 @@ pub(crate) fn fd_readdir(
|
||||
|
||||
pub(crate) fn path_readlink(resolved: PathGet, buf: &mut [u8]) -> Result<usize> {
|
||||
use nix::errno::Errno;
|
||||
let path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| host::__WASI_EILSEQ)?;
|
||||
let path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
|
||||
// Linux requires that the buffer size is positive, whereas POSIX does not.
|
||||
// Use a fake buffer to store the results if the size is zero.
|
||||
@@ -307,9 +306,9 @@ pub(crate) fn path_readlink(resolved: PathGet, buf: &mut [u8]) -> Result<usize>
|
||||
pub(crate) fn path_rename(resolved_old: PathGet, resolved_new: PathGet) -> Result<()> {
|
||||
use nix::libc::renameat;
|
||||
let old_path_cstr =
|
||||
CString::new(resolved_old.path().as_bytes()).map_err(|_| host::__WASI_EILSEQ)?;
|
||||
CString::new(resolved_old.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let new_path_cstr =
|
||||
CString::new(resolved_new.path().as_bytes()).map_err(|_| host::__WASI_EILSEQ)?;
|
||||
CString::new(resolved_new.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
|
||||
let res = unsafe {
|
||||
renameat(
|
||||
@@ -329,27 +328,19 @@ pub(crate) fn path_rename(resolved_old: PathGet, resolved_new: PathGet) -> Resul
|
||||
pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<host::__wasi_filestat_t> {
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
|
||||
let metadata = file.metadata().map_err(errno_from_ioerror)?;
|
||||
let metadata = file.metadata()?;
|
||||
Ok(host::__wasi_filestat_t {
|
||||
st_dev: metadata.dev(),
|
||||
st_ino: metadata.ino(),
|
||||
st_nlink: metadata
|
||||
.nlink()
|
||||
.try_into()
|
||||
.map_err(|_| host::__WASI_EOVERFLOW)?, // u64 doesn't fit into u32
|
||||
.try_into()?, // u64 doesn't fit into u32
|
||||
st_size: metadata.len(),
|
||||
st_atim: metadata
|
||||
.accessed()
|
||||
.map_err(errno_from_ioerror)
|
||||
.and_then(systemtime_to_timestamp)?,
|
||||
st_atim: systemtime_to_timestamp(metadata.accessed()?)?,
|
||||
st_ctim: metadata
|
||||
.ctime()
|
||||
.try_into()
|
||||
.map_err(|_| host::__WASI_EOVERFLOW)?, // i64 doesn't fit into u64
|
||||
st_mtim: metadata
|
||||
.modified()
|
||||
.map_err(errno_from_ioerror)
|
||||
.and_then(systemtime_to_timestamp)?,
|
||||
.try_into()?, // i64 doesn't fit into u64
|
||||
st_mtim: systemtime_to_timestamp(metadata.modified()?)?,
|
||||
st_filetype: filetype(file, &metadata)?,
|
||||
})
|
||||
}
|
||||
@@ -432,7 +423,7 @@ pub(crate) fn path_filestat_set_times(
|
||||
let set_mtim_now = fst_flags & host::__WASI_FILESTAT_SET_MTIM_NOW != 0;
|
||||
|
||||
if (set_atim && set_atim_now) || (set_mtim && set_mtim_now) {
|
||||
return Err(host::__WASI_EINVAL);
|
||||
return Err(Error::EINVAL);
|
||||
}
|
||||
|
||||
let atflags = match dirflags {
|
||||
@@ -441,7 +432,7 @@ pub(crate) fn path_filestat_set_times(
|
||||
};
|
||||
|
||||
let atim = if set_atim_now {
|
||||
let st_atim = st_atim.try_into().map_err(|_| host::__WASI_EOVERFLOW)?;
|
||||
let st_atim = st_atim.try_into().map_err(|_| Error::EOVERFLOW)?;
|
||||
TimeSpec::nanoseconds(st_atim)
|
||||
} else if set_atim_now {
|
||||
timespec_now()
|
||||
@@ -450,7 +441,7 @@ pub(crate) fn path_filestat_set_times(
|
||||
};
|
||||
|
||||
let mtim = if set_mtim {
|
||||
let st_mtim = st_mtim.try_into().map_err(|_| host::__WASI_EOVERFLOW)?;
|
||||
let st_mtim = st_mtim.try_into().map_err(|_| Error::EOVERFLOW)?;
|
||||
TimeSpec::nanoseconds(st_mtim)
|
||||
} else if set_atim_now {
|
||||
timespec_now()
|
||||
@@ -466,9 +457,9 @@ pub(crate) fn path_filestat_set_times(
|
||||
pub(crate) fn path_symlink(old_path: &str, resolved: PathGet) -> Result<()> {
|
||||
use nix::libc::symlinkat;
|
||||
|
||||
let old_path_cstr = CString::new(old_path.as_bytes()).map_err(|_| host::__WASI_EILSEQ)?;
|
||||
let old_path_cstr = CString::new(old_path.as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
let new_path_cstr =
|
||||
CString::new(resolved.path().as_bytes()).map_err(|_| host::__WASI_EILSEQ)?;
|
||||
CString::new(resolved.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
|
||||
let res = unsafe {
|
||||
symlinkat(
|
||||
@@ -488,7 +479,7 @@ pub(crate) fn path_unlink_file(resolved: PathGet) -> Result<()> {
|
||||
use nix::errno;
|
||||
use nix::libc::unlinkat;
|
||||
|
||||
let path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| host::__WASI_EILSEQ)?;
|
||||
let path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
|
||||
// nix doesn't expose unlinkat() yet
|
||||
match unsafe { unlinkat(resolved.dirfd().as_raw_fd(), path_cstr.as_ptr(), 0) } {
|
||||
@@ -532,7 +523,7 @@ pub(crate) fn path_remove_directory(resolved: PathGet) -> Result<()> {
|
||||
use nix::errno;
|
||||
use nix::libc::{unlinkat, AT_REMOVEDIR};
|
||||
|
||||
let path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| host::__WASI_EILSEQ)?;
|
||||
let path_cstr = CString::new(resolved.path().as_bytes()).map_err(|_| Error::EILSEQ)?;
|
||||
|
||||
// nix doesn't expose unlinkat() yet
|
||||
match unsafe {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#![allow(unused_unsafe)]
|
||||
use crate::memory::*;
|
||||
use crate::sys::host_impl;
|
||||
use crate::{host, wasm32, Result};
|
||||
use crate::{host, wasm32, Result, Error};
|
||||
use nix::libc::{self, c_int};
|
||||
use std::cmp;
|
||||
use std::time::SystemTime;
|
||||
@@ -14,7 +14,7 @@ pub(crate) fn clock_res_get(clock_id: host::__wasi_clockid_t) -> Result<host::__
|
||||
host::__WASI_CLOCK_MONOTONIC => libc::CLOCK_MONOTONIC,
|
||||
host::__WASI_CLOCK_PROCESS_CPUTIME_ID => libc::CLOCK_PROCESS_CPUTIME_ID,
|
||||
host::__WASI_CLOCK_THREAD_CPUTIME_ID => libc::CLOCK_THREAD_CPUTIME_ID,
|
||||
_ => return Err(host::__WASI_EINVAL),
|
||||
_ => return Err(Error::EINVAL),
|
||||
};
|
||||
|
||||
// no `nix` wrapper for clock_getres, so we do it ourselves
|
||||
@@ -30,11 +30,11 @@ pub(crate) fn clock_res_get(clock_id: host::__wasi_clockid_t) -> Result<host::__
|
||||
(timespec.tv_sec as host::__wasi_timestamp_t)
|
||||
.checked_mul(1_000_000_000)
|
||||
.and_then(|sec_ns| sec_ns.checked_add(timespec.tv_nsec as host::__wasi_timestamp_t))
|
||||
.map_or(Err(host::__WASI_EOVERFLOW), |resolution| {
|
||||
.map_or(Err(Error::EOVERFLOW), |resolution| {
|
||||
// a supported clock can never return zero; this case will probably never get hit, but
|
||||
// make sure we follow the spec
|
||||
if resolution == 0 {
|
||||
Err(host::__WASI_EINVAL)
|
||||
Err(Error::EINVAL)
|
||||
} else {
|
||||
Ok(resolution)
|
||||
}
|
||||
@@ -48,7 +48,7 @@ pub(crate) fn clock_time_get(clock_id: host::__wasi_clockid_t) -> Result<host::_
|
||||
host::__WASI_CLOCK_MONOTONIC => libc::CLOCK_MONOTONIC,
|
||||
host::__WASI_CLOCK_PROCESS_CPUTIME_ID => libc::CLOCK_PROCESS_CPUTIME_ID,
|
||||
host::__WASI_CLOCK_THREAD_CPUTIME_ID => libc::CLOCK_THREAD_CPUTIME_ID,
|
||||
_ => return Err(host::__WASI_EINVAL),
|
||||
_ => return Err(Error::EINVAL),
|
||||
};
|
||||
|
||||
// no `nix` wrapper for clock_getres, so we do it ourselves
|
||||
@@ -63,7 +63,7 @@ pub(crate) fn clock_time_get(clock_id: host::__wasi_clockid_t) -> Result<host::_
|
||||
(timespec.tv_sec as host::__wasi_timestamp_t)
|
||||
.checked_mul(1_000_000_000)
|
||||
.and_then(|sec_ns| sec_ns.checked_add(timespec.tv_nsec as host::__wasi_timestamp_t))
|
||||
.map_or(Err(host::__WASI_EOVERFLOW), |time| Ok(time))
|
||||
.map_or(Err(Error::EOVERFLOW), |time| Ok(time))
|
||||
}
|
||||
|
||||
pub(crate) fn poll_oneoff(
|
||||
@@ -152,7 +152,7 @@ fn wasi_clock_to_relative_ns_delay(
|
||||
}
|
||||
let now: u128 = SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.map_err(|_| host::__WASI_ENOTCAPABLE)?
|
||||
.map_err(|_| Error::ENOTCAPABLE)?
|
||||
.as_nanos();
|
||||
let deadline = wasi_clock.timeout as u128;
|
||||
Ok(deadline.saturating_sub(now))
|
||||
|
||||
@@ -2,15 +2,14 @@ pub(crate) mod fdentry_impl;
|
||||
pub(crate) mod host_impl;
|
||||
pub(crate) mod hostcalls_impl;
|
||||
|
||||
use crate::sys::errno_from_ioerror;
|
||||
use crate::Result;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
|
||||
pub(crate) fn dev_null() -> Result<File> {
|
||||
File::open("/dev/null").map_err(errno_from_ioerror)
|
||||
File::open("/dev/null").map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn preopen_dir<P: AsRef<Path>>(path: P) -> Result<File> {
|
||||
File::open(path).map_err(errno_from_ioerror)
|
||||
File::open(path).map_err(Into::into)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::host_impl;
|
||||
use crate::fdentry::Descriptor;
|
||||
use crate::{host, Result};
|
||||
use crate::{host, Error, Result};
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::os::windows::prelude::{AsRawHandle, FromRawHandle, RawHandle};
|
||||
@@ -29,8 +28,7 @@ pub(crate) fn determine_type_and_access_rights<Handle: AsRawHandle>(
|
||||
|
||||
match file_type {
|
||||
host::__WASI_FILETYPE_DIRECTORY | host::__WASI_FILETYPE_REGULAR_FILE => {
|
||||
let mode =
|
||||
get_file_access_mode(handle.as_raw_handle()).map_err(host_impl::errno_from_win)?;
|
||||
let mode = get_file_access_mode(handle.as_raw_handle())?;
|
||||
if mode.contains(AccessMode::FILE_GENERIC_READ) {
|
||||
rights_base |= host::__WASI_RIGHT_FD_READ;
|
||||
}
|
||||
@@ -55,8 +53,7 @@ pub(crate) fn determine_type_rights<Handle: AsRawHandle>(
|
||||
host::__wasi_rights_t,
|
||||
)> {
|
||||
let (file_type, rights_base, rights_inheriting) = {
|
||||
let file_type =
|
||||
winx::file::get_file_type(handle.as_raw_handle()).map_err(host_impl::errno_from_win)?;
|
||||
let file_type = winx::file::get_file_type(handle.as_raw_handle())?;
|
||||
if file_type.is_char() {
|
||||
// character file: LPT device or console
|
||||
// TODO: rule out LPT device
|
||||
@@ -70,7 +67,7 @@ pub(crate) fn determine_type_rights<Handle: AsRawHandle>(
|
||||
let file = std::mem::ManuallyDrop::new(unsafe {
|
||||
File::from_raw_handle(handle.as_raw_handle())
|
||||
});
|
||||
let meta = file.metadata().map_err(|_| host::__WASI_EINVAL)?;
|
||||
let meta = file.metadata().map_err(|_| Error::EINVAL)?;
|
||||
if meta.is_dir() {
|
||||
(
|
||||
host::__WASI_FILETYPE_DIRECTORY,
|
||||
@@ -84,7 +81,7 @@ pub(crate) fn determine_type_rights<Handle: AsRawHandle>(
|
||||
host::RIGHTS_REGULAR_FILE_INHERITING,
|
||||
)
|
||||
} else {
|
||||
return Err(host::__WASI_EINVAL);
|
||||
return Err(Error::EINVAL);
|
||||
}
|
||||
} else if file_type.is_pipe() {
|
||||
// pipe object: socket, named pipe or anonymous pipe
|
||||
@@ -95,7 +92,7 @@ pub(crate) fn determine_type_rights<Handle: AsRawHandle>(
|
||||
host::RIGHTS_SOCKET_INHERITING,
|
||||
)
|
||||
} else {
|
||||
return Err(host::__WASI_EINVAL);
|
||||
return Err(Error::EINVAL);
|
||||
}
|
||||
};
|
||||
Ok((file_type, rights_base, rights_inheriting))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(unused)]
|
||||
use crate::{host, Result};
|
||||
use crate::{host, Result, Error};
|
||||
use std::ffi::OsStr;
|
||||
use std::fs::OpenOptions;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
@@ -102,5 +102,5 @@ pub(crate) fn win_from_oflags(oflags: host::__wasi_oflags_t) -> CreationDisposit
|
||||
/// `__WASI_EILSEQ` error is returned.
|
||||
pub(crate) fn path_from_host<S: AsRef<OsStr>>(s: S) -> Result<String> {
|
||||
let vec: Vec<u16> = s.as_ref().encode_wide().collect();
|
||||
String::from_utf16(&vec).map_err(|_| host::__WASI_EILSEQ)
|
||||
String::from_utf16(&vec).map_err(|_| Error::EILSEQ)
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ use crate::hostcalls_impl::{fd_filestat_set_times_impl, PathGet};
|
||||
use crate::sys::fdentry_impl::determine_type_rights;
|
||||
use crate::sys::host_impl;
|
||||
use crate::sys::hostcalls_impl::fs_helpers::PathGetExt;
|
||||
use crate::sys::{errno_from_host, errno_from_ioerror};
|
||||
use crate::{host, Result};
|
||||
use crate::{host, Error, Result};
|
||||
use std::convert::TryInto;
|
||||
use std::fs::{File, Metadata, OpenOptions};
|
||||
use std::io::{self, Seek, SeekFrom};
|
||||
@@ -37,23 +36,25 @@ fn write_at(mut file: &File, buf: &[u8], offset: u64) -> io::Result<usize> {
|
||||
Ok(nwritten)
|
||||
}
|
||||
|
||||
// TODO refactor common code with unix
|
||||
pub(crate) fn fd_pread(
|
||||
file: &File,
|
||||
buf: &mut [u8],
|
||||
offset: host::__wasi_filesize_t,
|
||||
) -> Result<usize> {
|
||||
read_at(file, buf, offset).map_err(errno_from_ioerror)
|
||||
read_at(file, buf, offset).map_err(Into::into)
|
||||
}
|
||||
|
||||
// TODO refactor common code with unix
|
||||
pub(crate) fn fd_pwrite(file: &File, buf: &[u8], offset: host::__wasi_filesize_t) -> Result<usize> {
|
||||
write_at(file, buf, offset).map_err(errno_from_ioerror)
|
||||
write_at(file, buf, offset).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub(crate) fn fd_fdstat_get(fd: &File) -> Result<host::__wasi_fdflags_t> {
|
||||
use winx::file::AccessMode;
|
||||
winx::file::get_file_access_mode(fd.as_raw_handle())
|
||||
.map(host_impl::fdflags_from_win)
|
||||
.map_err(host_impl::errno_from_win)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub(crate) fn fd_fdstat_set_flags(fd: &File, fdflags: host::__wasi_fdflags_t) -> Result<()> {
|
||||
@@ -81,7 +82,7 @@ pub(crate) fn fd_advise(
|
||||
|
||||
pub(crate) fn path_create_directory(resolved: PathGet) -> Result<()> {
|
||||
let path = resolved.concatenate()?;
|
||||
std::fs::create_dir(&path).map_err(errno_from_ioerror)
|
||||
std::fs::create_dir(&path).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub(crate) fn path_link(resolved_old: PathGet, resolved_new: PathGet) -> Result<()> {
|
||||
@@ -133,11 +134,11 @@ pub(crate) fn path_open(
|
||||
Ok(file_type) => {
|
||||
// check if we are trying to open a symlink
|
||||
if file_type.is_symlink() {
|
||||
return Err(host::__WASI_ELOOP);
|
||||
return Err(Error::ELOOP);
|
||||
}
|
||||
// check if we are trying to open a file as a dir
|
||||
if file_type.is_file() && oflags & host::__WASI_O_DIRECTORY != 0 {
|
||||
return Err(host::__WASI_ENOTDIR);
|
||||
return Err(Error::ENOTDIR);
|
||||
}
|
||||
}
|
||||
Err(e) => match e.raw_os_error() {
|
||||
@@ -147,14 +148,14 @@ pub(crate) fn path_open(
|
||||
let e = WinError::from_u32(e as u32);
|
||||
|
||||
if e != WinError::ERROR_FILE_NOT_FOUND {
|
||||
return Err(host_impl::errno_from_win(e));
|
||||
return Err(e.into());
|
||||
}
|
||||
// file not found, let it proceed to actually
|
||||
// trying to open it
|
||||
}
|
||||
None => {
|
||||
log::debug!("Inconvertible OS error: {}", e);
|
||||
return Err(host::__WASI_EIO);
|
||||
return Err(Error::EIO);
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -162,7 +163,7 @@ pub(crate) fn path_open(
|
||||
opts.access_mode(access_mode.bits())
|
||||
.custom_flags(flags.bits())
|
||||
.open(&path)
|
||||
.map_err(errno_from_ioerror)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub(crate) fn fd_readdir(
|
||||
@@ -177,19 +178,18 @@ pub(crate) fn path_readlink(resolved: PathGet, buf: &mut [u8]) -> Result<usize>
|
||||
use winx::file::get_path_by_handle;
|
||||
|
||||
let path = resolved.concatenate()?;
|
||||
let target_path = path.read_link().map_err(errno_from_ioerror)?;
|
||||
let target_path = path.read_link()?;
|
||||
|
||||
// since on Windows we are effectively emulating 'at' syscalls
|
||||
// we need to strip the prefix from the absolute path
|
||||
// as otherwise we will error out since WASI is not capable
|
||||
// of dealing with absolute paths
|
||||
let dir_path =
|
||||
get_path_by_handle(resolved.dirfd().as_raw_handle()).map_err(host_impl::errno_from_win)?;
|
||||
let dir_path = get_path_by_handle(resolved.dirfd().as_raw_handle())?;
|
||||
let dir_path = PathBuf::from(strip_extended_prefix(dir_path));
|
||||
let target_path = target_path
|
||||
.strip_prefix(dir_path)
|
||||
.map_err(|_| host::__WASI_ENOTCAPABLE)
|
||||
.and_then(|path| path.to_str().map(String::from).ok_or(host::__WASI_EILSEQ))?;
|
||||
.map_err(|_| Error::ENOTCAPABLE)
|
||||
.and_then(|path| path.to_str().map(String::from).ok_or(Error::EILSEQ))?;
|
||||
|
||||
if buf.len() > 0 {
|
||||
let mut chars = target_path.chars();
|
||||
@@ -222,7 +222,7 @@ pub(crate) fn path_rename(resolved_old: PathGet, resolved_new: PathGet) -> Resul
|
||||
//
|
||||
// [std::fs::rename]: https://doc.rust-lang.org/std/fs/fn.rename.html
|
||||
if old_path.is_dir() && new_path.is_file() {
|
||||
return Err(host::__WASI_ENOTDIR);
|
||||
return Err(Error::ENOTDIR);
|
||||
}
|
||||
|
||||
// TODO handle symlinks
|
||||
@@ -237,21 +237,21 @@ pub(crate) fn path_rename(resolved_old: PathGet, resolved_new: PathGet) -> Resul
|
||||
// So most likely dealing with new_path == dir.
|
||||
// Eliminate case old_path == file first.
|
||||
if old_path.is_file() {
|
||||
Err(host::__WASI_EISDIR)
|
||||
Err(Error::EISDIR)
|
||||
} else {
|
||||
// Ok, let's try removing an empty dir at new_path if it exists
|
||||
// and is a nonempty dir.
|
||||
fs::remove_dir(&new_path)
|
||||
.and_then(|()| fs::rename(old_path, new_path))
|
||||
.map_err(errno_from_ioerror)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
e => Err(host_impl::errno_from_win(e)),
|
||||
e => Err(e.into()),
|
||||
}
|
||||
}
|
||||
None => {
|
||||
log::debug!("Inconvertible OS error: {}", e);
|
||||
Err(host::__WASI_EIO)
|
||||
Err(Error::EIO)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -277,27 +277,15 @@ pub(crate) fn change_time(file: &File, _metadata: &Metadata) -> io::Result<i64>
|
||||
}
|
||||
|
||||
pub(crate) fn fd_filestat_get_impl(file: &std::fs::File) -> Result<host::__wasi_filestat_t> {
|
||||
let metadata = file.metadata().map_err(errno_from_ioerror)?;
|
||||
let metadata = file.metadata()?;
|
||||
Ok(host::__wasi_filestat_t {
|
||||
st_dev: device_id(file, &metadata).map_err(errno_from_ioerror)?,
|
||||
st_ino: file_serial_no(file, &metadata).map_err(errno_from_ioerror)?,
|
||||
st_nlink: num_hardlinks(file, &metadata)
|
||||
.map_err(errno_from_ioerror)?
|
||||
.try_into()
|
||||
.map_err(|_| host::__WASI_EOVERFLOW)?, // u64 doesn't fit into u32
|
||||
st_dev: device_id(file, &metadata)?,
|
||||
st_ino: file_serial_no(file, &metadata)?,
|
||||
st_nlink: num_hardlinks(file, &metadata)?.try_into()?, // u64 doesn't fit into u32
|
||||
st_size: metadata.len(),
|
||||
st_atim: metadata
|
||||
.accessed()
|
||||
.map_err(errno_from_ioerror)
|
||||
.and_then(systemtime_to_timestamp)?,
|
||||
st_ctim: change_time(file, &metadata)
|
||||
.map_err(errno_from_ioerror)?
|
||||
.try_into()
|
||||
.map_err(|_| host::__WASI_EOVERFLOW)?, // i64 doesn't fit into u64
|
||||
st_mtim: metadata
|
||||
.modified()
|
||||
.map_err(errno_from_ioerror)
|
||||
.and_then(systemtime_to_timestamp)?,
|
||||
st_atim: systemtime_to_timestamp(metadata.accessed()?)?,
|
||||
st_ctim: change_time(file, &metadata)?.try_into()?, // i64 doesn't fit into u64
|
||||
st_mtim: systemtime_to_timestamp(metadata.modified()?)?,
|
||||
st_filetype: filetype(file, &metadata)?,
|
||||
})
|
||||
}
|
||||
@@ -322,7 +310,7 @@ pub(crate) fn path_filestat_get(
|
||||
dirflags: host::__wasi_lookupflags_t,
|
||||
) -> Result<host::__wasi_filestat_t> {
|
||||
let path = resolved.concatenate()?;
|
||||
let file = File::open(path).map_err(errno_from_ioerror)?;
|
||||
let file = File::open(path)?;
|
||||
fd_filestat_get_impl(&file)
|
||||
}
|
||||
|
||||
@@ -337,8 +325,7 @@ pub(crate) fn path_filestat_set_times(
|
||||
let path = resolved.concatenate()?;
|
||||
let file = OpenOptions::new()
|
||||
.access_mode(AccessMode::FILE_WRITE_ATTRIBUTES.bits())
|
||||
.open(path)
|
||||
.map_err(errno_from_ioerror)?;
|
||||
.open(path)?;
|
||||
fd_filestat_set_times_impl(&file, st_atim, st_mtim, fst_flags)
|
||||
}
|
||||
|
||||
@@ -357,14 +344,14 @@ pub(crate) fn path_symlink(old_path: &str, resolved: PathGet) -> Result<()> {
|
||||
match WinError::from_u32(e as u32) {
|
||||
WinError::ERROR_NOT_A_REPARSE_POINT => {
|
||||
// try creating a dir symlink instead
|
||||
symlink_dir(old_path, new_path).map_err(errno_from_ioerror)
|
||||
symlink_dir(old_path, new_path).map_err(Into::into)
|
||||
}
|
||||
e => Err(host_impl::errno_from_win(e)),
|
||||
e => Err(e.into()),
|
||||
}
|
||||
}
|
||||
None => {
|
||||
log::debug!("Inconvertible OS error: {}", e);
|
||||
Err(host::__WASI_EIO)
|
||||
Err(Error::EIO)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -377,8 +364,7 @@ pub(crate) fn path_unlink_file(resolved: PathGet) -> Result<()> {
|
||||
let path = resolved.concatenate()?;
|
||||
let file_type = path
|
||||
.symlink_metadata()
|
||||
.map(|metadata| metadata.file_type())
|
||||
.map_err(errno_from_ioerror)?;
|
||||
.map(|metadata| metadata.file_type())?;
|
||||
|
||||
// check if we're unlinking a symlink
|
||||
// NB this will get cleaned up a lot when [std::os::windows::fs::FileTypeExt]
|
||||
@@ -393,27 +379,27 @@ pub(crate) fn path_unlink_file(resolved: PathGet) -> Result<()> {
|
||||
match WinError::from_u32(e as u32) {
|
||||
WinError::ERROR_ACCESS_DENIED => {
|
||||
// try unlinking a dir symlink instead
|
||||
fs::remove_dir(path).map_err(errno_from_ioerror)
|
||||
fs::remove_dir(path).map_err(Into::into)
|
||||
}
|
||||
e => Err(host_impl::errno_from_win(e)),
|
||||
e => Err(e.into()),
|
||||
}
|
||||
}
|
||||
None => {
|
||||
log::debug!("Inconvertible OS error: {}", e);
|
||||
Err(host::__WASI_EIO)
|
||||
Err(Error::EIO)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else if file_type.is_dir() {
|
||||
Err(host::__WASI_EISDIR)
|
||||
Err(Error::EISDIR)
|
||||
} else if file_type.is_file() {
|
||||
fs::remove_file(path).map_err(errno_from_ioerror)
|
||||
fs::remove_file(path).map_err(Into::into)
|
||||
} else {
|
||||
Err(host::__WASI_EINVAL)
|
||||
Err(Error::EINVAL)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn path_remove_directory(resolved: PathGet) -> Result<()> {
|
||||
let path = resolved.concatenate()?;
|
||||
std::fs::remove_dir(&path).map_err(errno_from_ioerror)
|
||||
std::fs::remove_dir(&path).map_err(Into::into)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
use crate::sys::host_impl;
|
||||
use crate::{host, Result};
|
||||
use crate::hostcalls_impl::PathGet;
|
||||
use crate::{host, Error, Result};
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fs::File;
|
||||
use std::os::windows::ffi::{OsStrExt, OsStringExt};
|
||||
@@ -62,13 +61,13 @@ pub(crate) fn openat(dirfd: &File, path: &str) -> Result<File> {
|
||||
Some(e) => {
|
||||
log::debug!("openat error={:?}", e);
|
||||
match WinError::from_u32(e as u32) {
|
||||
WinError::ERROR_INVALID_NAME => host::__WASI_ENOTDIR,
|
||||
e => host_impl::errno_from_win(e),
|
||||
WinError::ERROR_INVALID_NAME => Error::ENOTDIR,
|
||||
e => e.into(),
|
||||
}
|
||||
}
|
||||
None => {
|
||||
log::debug!("Inconvertible OS error: {}", e);
|
||||
host::__WASI_EIO
|
||||
Error::EIO
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -84,13 +83,12 @@ pub(crate) fn readlinkat(dirfd: &File, s_path: &str) -> Result<String> {
|
||||
// we need to strip the prefix from the absolute path
|
||||
// as otherwise we will error out since WASI is not capable
|
||||
// of dealing with absolute paths
|
||||
let dir_path =
|
||||
get_path_by_handle(dirfd.as_raw_handle()).map_err(host_impl::errno_from_win)?;
|
||||
let dir_path = get_path_by_handle(dirfd.as_raw_handle())?;
|
||||
let dir_path = PathBuf::from(strip_extended_prefix(dir_path));
|
||||
target_path
|
||||
.strip_prefix(dir_path)
|
||||
.map_err(|_| host::__WASI_ENOTCAPABLE)
|
||||
.and_then(|path| path.to_str().map(String::from).ok_or(host::__WASI_EILSEQ))
|
||||
.map_err(|_| Error::ENOTCAPABLE)
|
||||
.and_then(|path| path.to_str().map(String::from).ok_or(Error::EILSEQ))
|
||||
}
|
||||
Err(e) => match e.raw_os_error() {
|
||||
Some(e) => {
|
||||
@@ -101,20 +99,20 @@ pub(crate) fn readlinkat(dirfd: &File, s_path: &str) -> Result<String> {
|
||||
// strip "/" and check if exists
|
||||
let path = concatenate(dirfd, Path::new(s_path.trim_end_matches('/')))?;
|
||||
if path.exists() && !path.is_dir() {
|
||||
Err(host::__WASI_ENOTDIR)
|
||||
Err(Error::ENOTDIR)
|
||||
} else {
|
||||
Err(host::__WASI_ENOENT)
|
||||
Err(Error::ENOENT)
|
||||
}
|
||||
} else {
|
||||
Err(host::__WASI_ENOENT)
|
||||
Err(Error::ENOENT)
|
||||
}
|
||||
}
|
||||
e => Err(host_impl::errno_from_win(e)),
|
||||
e => Err(e.into()),
|
||||
}
|
||||
}
|
||||
None => {
|
||||
log::debug!("Inconvertible OS error: {}", e);
|
||||
Err(host::__WASI_EIO)
|
||||
Err(Error::EIO)
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -135,10 +133,10 @@ pub(crate) fn concatenate<P: AsRef<Path>>(dirfd: &File, path: P) -> Result<PathB
|
||||
// WASI is not able to deal with absolute paths
|
||||
// so error out if absolute
|
||||
if path.as_ref().is_absolute() {
|
||||
return Err(host::__WASI_ENOTCAPABLE);
|
||||
return Err(Error::ENOTCAPABLE);
|
||||
}
|
||||
|
||||
let dir_path = get_path_by_handle(dirfd.as_raw_handle()).map_err(host_impl::errno_from_win)?;
|
||||
let dir_path = get_path_by_handle(dirfd.as_raw_handle())?;
|
||||
// concatenate paths
|
||||
let mut out_path = PathBuf::from(dir_path);
|
||||
out_path.push(path.as_ref());
|
||||
|
||||
@@ -2,13 +2,12 @@ pub(crate) mod fdentry_impl;
|
||||
pub(crate) mod host_impl;
|
||||
pub(crate) mod hostcalls_impl;
|
||||
|
||||
use crate::sys::errno_from_ioerror;
|
||||
use crate::Result;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
|
||||
pub(crate) fn dev_null() -> Result<File> {
|
||||
File::open("NUL").map_err(errno_from_ioerror)
|
||||
File::open("NUL").map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn preopen_dir<P: AsRef<Path>>(path: P) -> Result<File> {
|
||||
@@ -25,5 +24,5 @@ pub fn preopen_dir<P: AsRef<Path>>(path: P) -> Result<File> {
|
||||
.read(true)
|
||||
.attributes(FILE_FLAG_BACKUP_SEMANTICS)
|
||||
.open(path)
|
||||
.map_err(errno_from_ioerror)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user