diff --git a/Cargo.lock b/Cargo.lock index cb5a601f55..ae8c74214e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -993,7 +993,7 @@ dependencies = [ "cc", "libc", "log", - "rustc_version", + "rustc_version 0.2.3", "winapi", ] @@ -1558,6 +1558,15 @@ dependencies = [ name = "peepmatic-traits" version = "0.69.0" +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + [[package]] name = "pin-project-lite" version = "0.2.0" @@ -1790,7 +1799,7 @@ checksum = "1fdf7d9dbd43f3d81d94a49c1c3df73cc2b3827995147e6cf7f89d4ec5483e73" dependencies = [ "bitflags", "cc", - "rustc_version", + "rustc_version 0.2.3", ] [[package]] @@ -1934,7 +1943,16 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "semver", + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", ] [[package]] @@ -2002,7 +2020,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser", + "semver-parser 0.7.0", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser 0.10.2", ] [[package]] @@ -2011,6 +2038,15 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "serde" version = "1.0.118" @@ -2153,14 +2189,17 @@ dependencies = [ [[package]] name = "system-interface" -version = "0.2.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95457b1e5a9657ffd02a43048aeb083f20848d82176c0e1313facc1a23ba74da" +checksum = "2f4491d080ba27a6e906f264ad9b3d3db925b53160e71df56e65973441a186ab" dependencies = [ "atty", + "cap-std", "posish", + "rustc_version 0.3.3", + "unsafe-io", "winapi", - "winx 0.21.0", + "winx 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2384,6 +2423,12 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + [[package]] name = "unicode-segmentation" version = "1.7.1" @@ -2411,6 +2456,15 @@ dependencies = [ "traitobject", ] +[[package]] +name = "unsafe-io" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80ba583908d065c07f1eaf5eb389b9454f8bc735d182c8b93538e274568509b0" +dependencies = [ + "rustc_version 0.3.3", +] + [[package]] name = "vec_map" version = "0.8.2" @@ -3088,6 +3142,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "winx" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d35176e4c7e0daf9d8da18b7e9df81a8f2358fb3d6feea775ce810f974a512" +dependencies = [ + "bitflags", + "cvt", + "winapi", +] + [[package]] name = "witx" version = "0.8.8" diff --git a/crates/wasi-c2/Cargo.toml b/crates/wasi-c2/Cargo.toml index 752f26a992..848e69051d 100644 --- a/crates/wasi-c2/Cargo.toml +++ b/crates/wasi-c2/Cargo.toml @@ -24,7 +24,7 @@ thiserror = "1.0" libc = "0.2" wiggle = { path = "../wiggle", default-features = false, version = "0.22.0" } tracing = "0.1.19" -system-interface = "0.2" +system-interface = { version = "0.5", features = ["cap_std_impls"] } cap-std = "0.9" cap-fs-ext = "0.9" cap-time-ext = "0.9" diff --git a/crates/wasi-c2/src/file.rs b/crates/wasi-c2/src/file.rs index 106f734a2f..d273b722a5 100644 --- a/crates/wasi-c2/src/file.rs +++ b/crates/wasi-c2/src/file.rs @@ -5,8 +5,9 @@ use std::any::Any; use std::cell::Ref; use std::ops::Deref; use system_interface::fs::FileIoExt; +use system_interface::io::ReadReady; -pub trait WasiFile: FileIoExt + SetTimes { +pub trait WasiFile: FileIoExt + SetTimes + ReadReady { fn as_any(&self) -> &dyn Any; fn datasync(&self) -> Result<(), Error>; fn sync(&self) -> Result<(), Error>; diff --git a/crates/wasi-c2/src/sched/sync.rs b/crates/wasi-c2/src/sched/sync.rs index 63c2ac8dbc..ae5a791884 100644 --- a/crates/wasi-c2/src/sched/sync.rs +++ b/crates/wasi-c2/src/sched/sync.rs @@ -72,10 +72,8 @@ mod unix { if let Some(revents) = pollfd.revents() { let (nbytes, rwsub) = match rwsub { Subscription::Read(sub) => { - (1, sub) - // XXX FIXME: query_nbytes in wasi-common/src/sys/poll.rs - // uses metadata.len - tell to calculate for regular files, - // ioctl(fd, FIONREAD) for large files + let ready = sub.file.num_ready_bytes()?; + (std::cmp::max(ready, 1), sub) } Subscription::Write(sub) => (0, sub), _ => unreachable!(), diff --git a/crates/wasi-c2/src/stdio.rs b/crates/wasi-c2/src/stdio.rs index 9ff0284b67..194c9e3f1f 100644 --- a/crates/wasi-c2/src/stdio.rs +++ b/crates/wasi-c2/src/stdio.rs @@ -3,6 +3,7 @@ use crate::Error; use std::any::Any; #[cfg(unix)] use std::os::unix::io::{AsRawFd, RawFd}; +use system_interface::io::ReadReady; pub struct Stdin(std::io::Stdin); @@ -17,6 +18,12 @@ impl AsRawFd for Stdin { } } +impl ReadReady for Stdin { + fn num_ready_bytes(&self) -> Result { + self.0.num_ready_bytes() + } +} + impl WasiFile for Stdin { fn as_any(&self) -> &dyn Any { self @@ -57,6 +64,12 @@ impl AsRawFd for Stdout { } } +impl ReadReady for Stdout { + fn num_ready_bytes(&self) -> Result { + Ok(0) + } +} + impl WasiFile for Stdout { fn as_any(&self) -> &dyn Any { self @@ -97,6 +110,12 @@ impl AsRawFd for Stderr { } } +impl ReadReady for Stderr { + fn num_ready_bytes(&self) -> Result { + Ok(0) + } +} + impl WasiFile for Stderr { fn as_any(&self) -> &dyn Any { self diff --git a/crates/wasi-c2/src/virt/pipe.rs b/crates/wasi-c2/src/virt/pipe.rs index 6196360b8b..aebf84de9f 100644 --- a/crates/wasi-c2/src/virt/pipe.rs +++ b/crates/wasi-c2/src/virt/pipe.rs @@ -15,6 +15,7 @@ use std::any::Any; use std::io::{self, Read, Write}; use std::sync::{Arc, RwLock}; use system_interface::fs::{Advice, FileIoExt}; +use system_interface::io::ReadReady; /// A virtual pipe read end. /// @@ -123,12 +124,6 @@ impl FileIoExt for ReadPipe { fn read_to_string(&self, buf: &mut String) -> io::Result { self.borrow().read_to_string(buf) } - fn bytes(self) -> io::Bytes { - panic!("impossible to implement, removing from trait") - } - fn take(self, limit: u64) -> io::Take { - panic!("impossible to implement, removing from trait") - } fn write(&self, buf: &[u8]) -> io::Result { Err(std::io::Error::from_raw_os_error(libc::EBADF)) } @@ -144,7 +139,7 @@ impl FileIoExt for ReadPipe { fn write_vectored(&self, bufs: &[io::IoSlice]) -> io::Result { Err(std::io::Error::from_raw_os_error(libc::EBADF)) } - fn write_fmt(&mut self, fmt: std::fmt::Arguments) -> io::Result<()> { + fn write_fmt(&self, fmt: std::fmt::Arguments) -> io::Result<()> { Err(std::io::Error::from_raw_os_error(libc::EBADF)) } fn flush(&self) -> io::Result<()> { @@ -156,6 +151,9 @@ impl FileIoExt for ReadPipe { fn stream_position(&self) -> io::Result { Err(std::io::Error::from_raw_os_error(libc::ESPIPE)) } + fn peek(&self, _buf: &mut [u8]) -> io::Result { + Err(std::io::Error::from_raw_os_error(libc::EBADF)) // XXX is this right? or do we have to implement this faithfully, and add a buffer of peeked values to handle during reads? + } } impl fs_set_times::SetTimes for ReadPipe { @@ -167,6 +165,13 @@ impl fs_set_times::SetTimes for ReadPipe { todo!() } } + +impl ReadReady for ReadPipe { + fn num_ready_bytes(&self) -> Result { + todo!() + } +} + impl WasiFile for ReadPipe { fn as_any(&self) -> &dyn Any { self @@ -296,12 +301,6 @@ impl FileIoExt for WritePipe { fn read_to_string(&self, buf: &mut String) -> io::Result { Err(std::io::Error::from_raw_os_error(libc::EBADF)) } - fn bytes(self) -> io::Bytes { - todo!() // removing from trait - } - fn take(self, limit: u64) -> io::Take { - todo!() // removing from trait - } fn write(&self, buf: &[u8]) -> io::Result { self.borrow().write(buf) } @@ -317,7 +316,7 @@ impl FileIoExt for WritePipe { fn write_vectored(&self, bufs: &[io::IoSlice]) -> io::Result { self.borrow().write_vectored(bufs) } - fn write_fmt(&mut self, fmt: std::fmt::Arguments) -> io::Result<()> { + fn write_fmt(&self, fmt: std::fmt::Arguments) -> io::Result<()> { self.borrow().write_fmt(fmt) } fn flush(&self) -> io::Result<()> { @@ -329,6 +328,9 @@ impl FileIoExt for WritePipe { fn stream_position(&self) -> io::Result { Err(std::io::Error::from_raw_os_error(libc::ESPIPE)) } + fn peek(&self, _buf: &mut [u8]) -> io::Result { + Err(std::io::Error::from_raw_os_error(libc::EBADF)) + } } impl fs_set_times::SetTimes for WritePipe { @@ -341,6 +343,12 @@ impl fs_set_times::SetTimes for WritePipe { } } +impl ReadReady for WritePipe { + fn num_ready_bytes(&self) -> Result { + Ok(0) + } +} + impl WasiFile for WritePipe { fn as_any(&self) -> &dyn Any { self