Initial error refactor

This commit is contained in:
Marcin Mielniczuk
2019-09-07 19:36:29 +02:00
committed by Jakub Konka
parent 85a41d449c
commit 14aaffd46f
22 changed files with 560 additions and 383 deletions

View File

@@ -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 => {

View File

@@ -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);
}
};

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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))

View File

@@ -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)
}

View File

@@ -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))

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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());

View File

@@ -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)
}