latest system-interface provides ReadReady::num_ready_bytes

This commit is contained in:
Pat Hickey
2021-01-19 14:39:20 -08:00
parent 7f7a0be938
commit 657024bd0d
6 changed files with 118 additions and 27 deletions

View File

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

View File

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

View File

@@ -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!(),

View File

@@ -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<u64, std::io::Error> {
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<u64, std::io::Error> {
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<u64, std::io::Error> {
Ok(0)
}
}
impl WasiFile for Stderr {
fn as_any(&self) -> &dyn Any {
self

View File

@@ -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<R: Read> FileIoExt for ReadPipe<R> {
fn read_to_string(&self, buf: &mut String) -> io::Result<usize> {
self.borrow().read_to_string(buf)
}
fn bytes(self) -> io::Bytes<std::fs::File> {
panic!("impossible to implement, removing from trait")
}
fn take(self, limit: u64) -> io::Take<std::fs::File> {
panic!("impossible to implement, removing from trait")
}
fn write(&self, buf: &[u8]) -> io::Result<usize> {
Err(std::io::Error::from_raw_os_error(libc::EBADF))
}
@@ -144,7 +139,7 @@ impl<R: Read> FileIoExt for ReadPipe<R> {
fn write_vectored(&self, bufs: &[io::IoSlice]) -> io::Result<usize> {
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<R: Read> FileIoExt for ReadPipe<R> {
fn stream_position(&self) -> io::Result<u64> {
Err(std::io::Error::from_raw_os_error(libc::ESPIPE))
}
fn peek(&self, _buf: &mut [u8]) -> io::Result<usize> {
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<R: Read> fs_set_times::SetTimes for ReadPipe<R> {
@@ -167,6 +165,13 @@ impl<R: Read> fs_set_times::SetTimes for ReadPipe<R> {
todo!()
}
}
impl<R: Read + Any> ReadReady for ReadPipe<R> {
fn num_ready_bytes(&self) -> Result<u64, std::io::Error> {
todo!()
}
}
impl<R: Read + Any> WasiFile for ReadPipe<R> {
fn as_any(&self) -> &dyn Any {
self
@@ -296,12 +301,6 @@ impl<W: Write> FileIoExt for WritePipe<W> {
fn read_to_string(&self, buf: &mut String) -> io::Result<usize> {
Err(std::io::Error::from_raw_os_error(libc::EBADF))
}
fn bytes(self) -> io::Bytes<std::fs::File> {
todo!() // removing from trait
}
fn take(self, limit: u64) -> io::Take<std::fs::File> {
todo!() // removing from trait
}
fn write(&self, buf: &[u8]) -> io::Result<usize> {
self.borrow().write(buf)
}
@@ -317,7 +316,7 @@ impl<W: Write> FileIoExt for WritePipe<W> {
fn write_vectored(&self, bufs: &[io::IoSlice]) -> io::Result<usize> {
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<W: Write> FileIoExt for WritePipe<W> {
fn stream_position(&self) -> io::Result<u64> {
Err(std::io::Error::from_raw_os_error(libc::ESPIPE))
}
fn peek(&self, _buf: &mut [u8]) -> io::Result<usize> {
Err(std::io::Error::from_raw_os_error(libc::EBADF))
}
}
impl<W: Write> fs_set_times::SetTimes for WritePipe<W> {
@@ -341,6 +343,12 @@ impl<W: Write> fs_set_times::SetTimes for WritePipe<W> {
}
}
impl<W: Write + Any> ReadReady for WritePipe<W> {
fn num_ready_bytes(&self) -> Result<u64, std::io::Error> {
Ok(0)
}
}
impl<W: Write + Any> WasiFile for WritePipe<W> {
fn as_any(&self) -> &dyn Any {
self