@@ -150,7 +150,10 @@ impl FileDescription for io::Stdin {
150150 helpers:: isolation_abort_error ( "`read` from stdin" ) ?;
151151}
152152let result = Read :: read ( & mut { self } , & mut bytes) ;
153- ecx. return_read_bytes_and_count ( ptr, & bytes, result, dest)
153+ match result {
154+ Ok ( read_size) => ecx. return_read_success ( ptr, & bytes, read_size, dest) ,
155+ Err ( e) => ecx. set_last_error_and_return ( e, dest) ,
156+ }
154157}
155158
156159fn is_tty ( & self , communicate_allowed : bool ) -> bool {
@@ -181,7 +184,10 @@ impl FileDescription for io::Stdout {
181184// the host -- there is no good in adding extra buffering
182185// here.
183186 io:: stdout ( ) . flush ( ) . unwrap ( ) ;
184- ecx. return_written_byte_count_or_error ( result, dest)
187+ match result {
188+ Ok ( write_size) => ecx. return_write_success ( write_size, dest) ,
189+ Err ( e) => ecx. set_last_error_and_return ( e, dest) ,
190+ }
185191}
186192
187193fn is_tty ( & self , communicate_allowed : bool ) -> bool {
@@ -207,7 +213,10 @@ impl FileDescription for io::Stderr {
207213// We allow writing to stderr even with isolation enabled.
208214// No need to flush, stderr is not buffered.
209215let result = Write :: write ( & mut { self } , bytes) ;
210- ecx. return_written_byte_count_or_error ( result, dest)
216+ match result {
217+ Ok ( write_size) => ecx. return_write_success ( write_size, dest) ,
218+ Err ( e) => ecx. set_last_error_and_return ( e, dest) ,
219+ }
211220}
212221
213222fn is_tty ( & self , communicate_allowed : bool ) -> bool {
@@ -234,8 +243,7 @@ impl FileDescription for NullOutput {
234243ecx : & mut MiriInterpCx < ' tcx > ,
235244) -> InterpResult < ' tcx > {
236245// We just don't write anything, but report to the user that we did.
237- let result = Ok ( len) ;
238- ecx. return_written_byte_count_or_error ( result, dest)
246+ ecx. return_write_success ( len, dest)
239247}
240248}
241249
@@ -655,46 +663,39 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
655663}
656664
657665/// Helper to implement `FileDescription::read`:
658- /// `result` should be the return value of some underlying `read` call that used `bytes` as its output buffer.
666+ /// This is only used when `read` is successful.
667+ /// `actual_read_size` should be the return value of some underlying `read` call that used
668+ /// `bytes` as its output buffer.
659669/// The length of `bytes` must not exceed either the host's or the target's `isize`.
660- /// If `Result` indicates success, `bytes` is written to `buf` and the size is written to `dest`.
661- /// Otherwise, `-1` is written to `dest` and the last libc error is set appropriately.
662- fn return_read_bytes_and_count (
670+ /// `bytes` is written to `buf` and the size is written to `dest`.
671+ fn return_read_success (
663672& mut self ,
664673buf : Pointer ,
665674bytes : & [ u8 ] ,
666- result : io :: Result < usize > ,
675+ actual_read_size : usize ,
667676dest : & MPlaceTy < ' tcx > ,
668677) -> InterpResult < ' tcx > {
669678let this = self . eval_context_mut ( ) ;
670- match result {
671- Ok ( read_bytes) => {
672- // If reading to `bytes` did not fail, we write those bytes to the buffer.
673- // Crucially, if fewer than `bytes.len()` bytes were read, only write
674- // that much into the output buffer!
675- this. write_bytes_ptr ( buf, bytes[ ..read_bytes] . iter ( ) . copied ( ) ) ?;
676- // The actual read size is always less than what got originally requested so this cannot fail.
677- this. write_int ( u64:: try_from ( read_bytes) . unwrap ( ) , dest) ?;
678- Ok ( ( ) )
679- }
680- Err ( e) => {
681- this. set_last_error_from_io_error ( e) ?;
682- this. write_int ( -1 , dest) ?;
683- Ok ( ( ) )
684- }
685- }
679+ // If reading to `bytes` did not fail, we write those bytes to the buffer.
680+ // Crucially, if fewer than `bytes.len()` bytes were read, only write
681+ // that much into the output buffer!
682+ this. write_bytes_ptr ( buf, bytes[ ..actual_read_size] . iter ( ) . copied ( ) ) ?;
683+
684+ // The actual read size is always less than what got originally requested so this cannot fail.
685+ this. write_int ( u64:: try_from ( actual_read_size) . unwrap ( ) , dest) ?;
686+ Ok ( ( ) )
686687}
687688
688- /// This function writes the number of written bytes (given in `result`) to `dest`, or sets the
689- /// last libc error and writes -1 to dest.
690- fn return_written_byte_count_or_error (
689+ /// Helper to implement `FileDescription::write`:
690+ /// This function is only used when `write` is successful, and writes `actual_write_size` to ` dest`
691+ fn return_write_success (
691692& mut self ,
692- result : io :: Result < usize > ,
693+ actual_write_size : usize ,
693694dest : & MPlaceTy < ' tcx > ,
694695) -> InterpResult < ' tcx > {
695696let this = self . eval_context_mut ( ) ;
696- let result = this. try_unwrap_io_result ( result . map ( |c| i64 :: try_from ( c ) . unwrap ( ) ) ) ? ;
697- this. write_int ( result , dest) ?;
697+ // The actual write size is always less than what got originally requested so this cannot fail.
698+ this. write_int ( u64 :: try_from ( actual_write_size ) . unwrap ( ) , dest) ?;
698699Ok ( ( ) )
699700}
700701}
0 commit comments