[wasi-common]: yanix now returns io::Error directly (#1242)
* Yanix now returns io::Error This commit may seem somewhat controversial at first, but hear me out first. Currently, Yanix would return a custom error that's a wrapper around three other error types returned by various entities inside Rust's `libstd`. In particular, Yanix's error type would wrap `io::Error`, `num::TryFromIntError` and `ffi::NulError`. It turns out that there is a natural conversion between the first and the last and provided by the standard library, i.e., `From<ffi::NulError> for io::Error` is provided. So at the surface it may seem that only the first two wrapped error types are worth keeping. Digging a little bit deeper into `libstd`, `num::TryFromIntError` is essentially speaking only a marker that the integral conversion went wrong. The struct implementing this error stores a unit type, and nothing more. It therefore seems like a waste to wrap this particular error when we could unify everything under `io::Error`. And so, whenever we perform an int conversion, I suggest we simply remap the error to `io::Error::from_raw_os_error(libc::EOVERFLOW)` since this carries a comparable amount of information. As a result of completely discarding `yanix::Error` custom error type, we are invariably simplifying `yanix` itself, but also allowing `wasi-common` to simplify in several places as well. * Adapt wasi-common to changes in yanix * Add Cargo.lock * Unwrap try_into's where possible * Remove unnecessary type annotation
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
use crate::{
|
||||
dir::{Dir, Entry, EntryExt, SeekLoc},
|
||||
Result,
|
||||
use crate::dir::{Dir, Entry, EntryExt, SeekLoc};
|
||||
use std::{
|
||||
io::{Error, Result},
|
||||
ops::Deref,
|
||||
};
|
||||
use std::{io, ops::Deref};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub(crate) struct EntryImpl {
|
||||
@@ -19,17 +19,17 @@ impl Deref for EntryImpl {
|
||||
}
|
||||
|
||||
pub(crate) fn iter_impl(dir: &Dir) -> Option<Result<EntryImpl>> {
|
||||
let errno = io::Error::last_os_error();
|
||||
let errno = Error::last_os_error();
|
||||
let dirent = unsafe { libc::readdir(dir.as_raw().as_ptr()) };
|
||||
if dirent.is_null() {
|
||||
let curr_errno = io::Error::last_os_error();
|
||||
let curr_errno = Error::last_os_error();
|
||||
if errno.raw_os_error() != curr_errno.raw_os_error() {
|
||||
// TODO This should be verified on different BSD-flavours.
|
||||
//
|
||||
// According to 4.3BSD/POSIX.1-2001 man pages, there was an error
|
||||
// if the errno value has changed at some point during the sequence
|
||||
// of readdir calls.
|
||||
Some(Err(curr_errno.into()))
|
||||
Some(Err(curr_errno))
|
||||
} else {
|
||||
// Not an error. We've simply reached the end of the stream.
|
||||
None
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{Error, Result};
|
||||
use std::{convert::TryInto, os::unix::prelude::*};
|
||||
use crate::from_success_code;
|
||||
use std::{convert::TryInto, io::Result, os::unix::prelude::*};
|
||||
|
||||
#[cfg(not(any(target_os = "freebsd", target_os = "netbsd")))]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -44,11 +44,22 @@ pub unsafe fn posix_fadvise(
|
||||
// off_t ra_offset; /* offset into the file */
|
||||
// int ra_count; /* size of the read */
|
||||
// };
|
||||
let ra_count = match len.try_into() {
|
||||
Ok(ra_count) => ra_count,
|
||||
Err(_) => {
|
||||
// This conversion can fail, because it's converting into int. But in that case, the user
|
||||
// is providing a dubiously large hint. This is not confirmed (no helpful info in the man
|
||||
// pages), but offhand, a 2+ GiB advisory read async seems unlikely to help with any kind
|
||||
// of performance, so we log and exit early with a no-op.
|
||||
log::warn!("`len` too big to fit in the host's command. Returning early with no-op!");
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
let advisory = libc::radvisory {
|
||||
ra_offset: offset,
|
||||
ra_count: len.try_into()?,
|
||||
ra_count,
|
||||
};
|
||||
Error::from_success_code(libc::fcntl(fd, libc::F_RDADVISE, &advisory))
|
||||
from_success_code(libc::fcntl(fd, libc::F_RDADVISE, &advisory))
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "freebsd", target_os = "netbsd"))]
|
||||
@@ -58,7 +69,7 @@ pub unsafe fn posix_fadvise(
|
||||
len: libc::off_t,
|
||||
advice: PosixFadviseAdvice,
|
||||
) -> Result<()> {
|
||||
Error::from_success_code(libc::posix_fadvise(fd, offset, len, advice as libc::c_int))
|
||||
from_success_code(libc::posix_fadvise(fd, offset, len, advice as libc::c_int))
|
||||
}
|
||||
|
||||
// On BSDs without support we leave it as no-op
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use crate::Result;
|
||||
use std::{io, os::unix::prelude::*};
|
||||
use std::{
|
||||
io::{Error, Result},
|
||||
os::unix::prelude::*,
|
||||
};
|
||||
|
||||
pub unsafe fn isatty(fd: RawFd) -> Result<bool> {
|
||||
let res = libc::isatty(fd);
|
||||
@@ -8,15 +10,11 @@ pub unsafe fn isatty(fd: RawFd) -> Result<bool> {
|
||||
Ok(true)
|
||||
} else {
|
||||
// ... otherwise 0 is returned, and errno is set to indicate the error.
|
||||
let errno = io::Error::last_os_error();
|
||||
if let Some(raw_errno) = errno.raw_os_error() {
|
||||
if raw_errno == libc::ENOTTY {
|
||||
Ok(false)
|
||||
} else {
|
||||
Err(errno.into())
|
||||
}
|
||||
let errno = Error::last_os_error();
|
||||
if errno.raw_os_error().unwrap() == libc::ENOTTY {
|
||||
Ok(false)
|
||||
} else {
|
||||
Err(errno.into())
|
||||
Err(errno)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user