diff --git a/crates/wasi-c2/src/file.rs b/crates/wasi-c2/src/file.rs index ccc0f4d48b..73d7a3abc5 100644 --- a/crates/wasi-c2/src/file.rs +++ b/crates/wasi-c2/src/file.rs @@ -135,6 +135,7 @@ bitflags! { const FILESTAT_GET = 0b1000000000; const FILESTAT_SET_SIZE = 0b10000000000; const FILESTAT_SET_TIMES = 0b100000000000; + const POLL_READWRITE = 0b1000000000000; } } diff --git a/crates/wasi-c2/src/snapshots/preview_1.rs b/crates/wasi-c2/src/snapshots/preview_1.rs index baf7fedf38..91ae2610b2 100644 --- a/crates/wasi-c2/src/snapshots/preview_1.rs +++ b/crates/wasi-c2/src/snapshots/preview_1.rs @@ -888,6 +888,8 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { events: &GuestPtr, nsubscriptions: types::Size, ) -> Result { + use cap_std::time::{Duration, SystemClock}; + let table = self.table(); let mut poll = Poll::new(); let subs = subs.as_array(nsubscriptions); @@ -895,13 +897,35 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx { let sub_ptr = sub_elem?; let sub = sub_ptr.read()?; match sub.u { - types::SubscriptionU::Clock(clock) => { - todo!() + types::SubscriptionU::Clock(clocksub) => match clocksub.id { + types::Clockid::Realtime => { + let clock = self.clocks.system.deref(); + let precision = Duration::from_micros(clocksub.precision); + let duration = Duration::from_micros(clocksub.timeout); + let deadline = if clocksub + .flags + .contains(types::Subclockflags::SUBSCRIPTION_CLOCK_ABSTIME) + { + SystemClock::UNIX_EPOCH + .checked_add(duration) + .ok_or(Error::Overflow)? + } else { + clock + .now(precision) + .checked_add(duration) + .ok_or(Error::Overflow)? + }; + poll.subscribe_system_timer(clock, deadline, precision, sub.userdata.into()) + } + _ => Err(Error::Inval)?, + }, + types::SubscriptionU::FdRead(readsub) => { + let fd = readsub.file_descriptor; + let file_entry: Ref = table.get(u32::from(fd))?; + let f = file_entry.get_cap(FileCaps::POLL_READWRITE)?; + poll.subscribe_read(f, sub.userdata.into()); } - types::SubscriptionU::FdRead(read) => { - todo!() - } - types::SubscriptionU::FdWrite(write) => { + types::SubscriptionU::FdWrite(writesub) => { todo!() } } @@ -1105,6 +1129,9 @@ impl From<&FileCaps> for types::Rights { if caps.contains(FileCaps::FILESTAT_SET_TIMES) { rights = rights | types::Rights::FD_FILESTAT_SET_TIMES; } + if caps.contains(FileCaps::POLL_READWRITE) { + rights = rights | types::Rights::POLL_FD_READWRITE; + } rights } } @@ -1149,6 +1176,9 @@ impl From<&types::Rights> for FileCaps { if rights.contains(types::Rights::FD_FILESTAT_SET_TIMES) { caps = caps | FileCaps::FILESTAT_SET_TIMES; } + if rights.contains(types::Rights::POLL_FD_READWRITE) { + caps = caps | FileCaps::POLL_READWRITE; + } caps } }