Return EINVAL in poll_oneoff with no events. (#838)
* Return EINVAL in poll_oneoff with no events. We adhere to WebAssembly/WASI#193. * Add a test for empty poll.
This commit is contained in:
committed by
Dan Gohman
parent
448faed5ca
commit
815576edc5
@@ -19,6 +19,18 @@ unsafe fn poll_oneoff_impl(r#in: &[wasi::Subscription], nexpected: usize) -> Vec
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn test_empty_poll() {
|
||||||
|
let r#in = [];
|
||||||
|
let mut out: Vec<wasi::Event> = Vec::new();
|
||||||
|
let error = wasi::poll_oneoff(r#in.as_ptr(), out.as_mut_ptr(), r#in.len())
|
||||||
|
.expect_err("empty poll_oneoff should fail");
|
||||||
|
assert_eq!(
|
||||||
|
error.raw_error(),
|
||||||
|
wasi::ERRNO_INVAL,
|
||||||
|
"error should be EINVAL"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn test_timeout() {
|
unsafe fn test_timeout() {
|
||||||
let clock = wasi::SubscriptionClock {
|
let clock = wasi::SubscriptionClock {
|
||||||
id: wasi::CLOCKID_MONOTONIC,
|
id: wasi::CLOCKID_MONOTONIC,
|
||||||
@@ -220,6 +232,7 @@ unsafe fn test_fd_readwrite_invalid_fd() {
|
|||||||
|
|
||||||
unsafe fn test_poll_oneoff(dir_fd: wasi::Fd) {
|
unsafe fn test_poll_oneoff(dir_fd: wasi::Fd) {
|
||||||
test_timeout();
|
test_timeout();
|
||||||
|
test_empty_poll();
|
||||||
// NB we assume that stdin/stdout/stderr are valid and open
|
// NB we assume that stdin/stdout/stderr are valid and open
|
||||||
// for the duration of the test case
|
// for the duration of the test case
|
||||||
test_stdin_read();
|
test_stdin_read();
|
||||||
|
|||||||
@@ -218,6 +218,12 @@ pub(crate) fn poll_oneoff(
|
|||||||
|
|
||||||
let mut timeout: Option<ClockEventData> = None;
|
let mut timeout: Option<ClockEventData> = None;
|
||||||
let mut fd_events = Vec::new();
|
let mut fd_events = Vec::new();
|
||||||
|
|
||||||
|
// As mandated by the WASI spec:
|
||||||
|
// > If `nsubscriptions` is 0, returns `errno::inval`.
|
||||||
|
if subscriptions.is_empty() {
|
||||||
|
return Err(Error::EINVAL);
|
||||||
|
}
|
||||||
for subscription in subscriptions {
|
for subscription in subscriptions {
|
||||||
match subscription.r#type {
|
match subscription.r#type {
|
||||||
wasi::__WASI_EVENTTYPE_CLOCK => {
|
wasi::__WASI_EVENTTYPE_CLOCK => {
|
||||||
@@ -280,6 +286,9 @@ pub(crate) fn poll_oneoff(
|
|||||||
log::debug!("poll_oneoff timeout = {:?}", timeout);
|
log::debug!("poll_oneoff timeout = {:?}", timeout);
|
||||||
log::debug!("poll_oneoff fd_events = {:?}", fd_events);
|
log::debug!("poll_oneoff fd_events = {:?}", fd_events);
|
||||||
|
|
||||||
|
// The underlying implementation should successfully and immediately return
|
||||||
|
// if no events have been passed. Such situation may occur if all provided
|
||||||
|
// events have been filtered out as errors in the code above.
|
||||||
hostcalls_impl::poll_oneoff(timeout, fd_events, &mut events)?;
|
hostcalls_impl::poll_oneoff(timeout, fd_events, &mut events)?;
|
||||||
|
|
||||||
let events_count = u32::try_from(events.len()).map_err(|_| Error::EOVERFLOW)?;
|
let events_count = u32::try_from(events.len()).map_err(|_| Error::EOVERFLOW)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user