Browse Source
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
pull/8621/head
Trevor Elliott
6 months ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with
29 additions and
4 deletions
crates/test-programs/src/bin/preview2_file_read_write.rs
crates/wasi/src/filesystem.rs
@ -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 \0 Hello, 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 \0 Hello, World! " ) ;
drop ( ready ) ;
drop ( stream ) ;
drop ( file ) ;
dir . unlink_file_at ( filename ) . unwrap ( ) ;
}
@ -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 | {
@ -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 ( ) )
@ -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 ( ) ) ) ,