Skip to content

Commit

Permalink
Backport 8611 to 21.0.0 (#8617)
Browse files Browse the repository at this point in the history
* wasi: Handle read(0) with file streams (#8611)

* Test that wasi file streams can handle read(0)

* Zero-sized reads don't fail for file streams

* Accidentally removed the `read(0)` when refactoring the test

* Update release notes
  • Loading branch information
elliottt committed May 14, 2024
1 parent 9899578 commit 2690964
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 4 deletions.
4 changes: 4 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ Unreleased.
subcommand.
[#8525](https://github.com/bytecodealliance/wasmtime/issues/8525)

* The `read` implementation for file input streams in wasmtime-wasi now
correctly handles zero-length reads.
[#8611](https://github.com/bytecodealliance/wasmtime/issues/8611)

--------------------------------------------------------------------------------

## 20.0.1
Expand Down
26 changes: 25 additions & 1 deletion crates/test-programs/src/bin/preview2_file_read_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,31 @@ fn main() {
let stream = file.read_via_stream(0).unwrap();
let contents = stream.blocking_read(100).unwrap();
assert_eq!(contents, b"\0\0\0\0\0Hello, World!");
drop((stream, file));
drop(stream);

// Test that file read streams behave like other read streams.
let mut buf = Vec::new();
let stream = file.read_via_stream(0).unwrap();
let ready = stream.subscribe();
loop {
ready.block();

match stream.read(0) {
Ok(chunk) => assert!(chunk.is_empty()),
Err(wasi::io::streams::StreamError::Closed) => break,
Err(e) => panic!("Failed checking stream state: {e:?}"),
}

match stream.read(4) {
Ok(chunk) => buf.extend(chunk),
Err(wasi::io::streams::StreamError::Closed) => break,
Err(e) => panic!("Failed reading stream: {e:?}"),
}
}
assert_eq!(buf, b"\0\0\0\0\0Hello, World!");
drop(ready);
drop(stream);
drop(file);

dir.unlink_file_at(filename).unwrap();
}
7 changes: 4 additions & 3 deletions crates/wasi/src/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ impl FileInputStream {
pub async fn read(&mut self, size: usize) -> Result<Bytes, StreamError> {
use system_interface::fs::FileIoExt;
let p = self.position;

let (r, mut buf) = self
.file
.spawn_blocking(move |f| {
Expand All @@ -256,7 +257,7 @@ impl FileInputStream {
(r, buf)
})
.await;
let n = read_result(r)?;
let n = read_result(r, size)?;
buf.truncate(n);
self.position += n as u64;
Ok(buf.freeze())
Expand All @@ -268,9 +269,9 @@ impl FileInputStream {
}
}

fn read_result(r: io::Result<usize>) -> Result<usize, StreamError> {
fn read_result(r: io::Result<usize>, size: usize) -> Result<usize, StreamError> {
match r {
Ok(0) => Err(StreamError::Closed),
Ok(0) if size > 0 => Err(StreamError::Closed),
Ok(n) => Ok(n),
Err(e) if e.kind() == std::io::ErrorKind::Interrupted => Ok(0),
Err(e) => Err(StreamError::LastOperationFailed(e.into())),
Expand Down

0 comments on commit 2690964

Please sign in to comment.