@@ -538,7 +538,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
538538 buf : Pointer ,
539539 count : u64 ,
540540 offset : Option < i128 > ,
541- ) -> InterpResult < ' tcx , Scalar > {
541+ dest : & MPlaceTy < ' tcx > ,
542+ ) -> InterpResult < ' tcx > {
542543 let this = self . eval_context_mut ( ) ;
543544
544545 // Isolation check is done via `FileDescriptor` trait.
@@ -558,50 +559,33 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
558559 // We temporarily dup the FD to be able to retain mutable access to `this`.
559560 let Some ( fd) = this. machine . fds . get ( fd) else {
560561 trace ! ( "read: FD not found" ) ;
561- return Ok ( Scalar :: from_target_isize ( this. fd_not_found ( ) ?, this) ) ;
562+ let res = Scalar :: from_target_isize ( this. fd_not_found ( ) ?, this) ;
563+ this. write_scalar ( res, dest) ?;
564+ return Ok ( ( ) ) ;
562565 } ;
563566
564567 trace ! ( "read: FD mapped to {fd:?}" ) ;
565568 // We want to read at most `count` bytes. We are sure that `count` is not negative
566569 // because it was a target's `usize`. Also we are sure that its smaller than
567570 // `usize::MAX` because it is bounded by the host's `isize`.
568571
569- // TODO: shouldn't pass vec, just pass pointer and write it.
572+ // TODO: shouldn't pass vec, just pass pointer and directly write to it.
570573 let mut bytes = vec ! [ 0 ; usize :: try_from( count) . unwrap( ) ] ;
571574 let result = match offset {
572575 None => fd. read ( & fd, communicate, & mut bytes, buf, this) ,
573576 Some ( offset) => {
574577 let Ok ( offset) = u64:: try_from ( offset) else {
575578 let einval = this. eval_libc ( "EINVAL" ) ;
576579 this. set_last_error ( einval) ?;
577- return Ok ( Scalar :: from_target_isize ( -1 , this) ) ;
580+ this. write_scalar ( Scalar :: from_target_isize ( -1 , this) , dest) ?;
581+ return Ok ( ( ) ) ;
578582 } ;
579583 fd. pread ( communicate, & mut bytes, offset, this)
580584 }
581585 } ;
582-
583- // `File::read` never returns a value larger than `count`, so this cannot fail.
584- match result?. map ( |c| i64:: try_from ( c) . unwrap ( ) ) {
585- // TODO: get the byte out the result, then write the ptr.
586- // try to pass this the write_ptr inside write
587- // Pass the pointer inside the write function.
588- Ok ( read_bytes) => {
589- // If reading to `bytes` did not fail, we write those bytes to the buffer.
590- // Crucially, if fewer than `bytes.len()` bytes were read, only write
591- // that much into the output buffer!
592-
593- // TODO: write to pointer here.
594- this. write_bytes_ptr (
595- buf,
596- bytes[ ..usize:: try_from ( read_bytes) . unwrap ( ) ] . iter ( ) . copied ( ) ,
597- ) ?;
598- Ok ( Scalar :: from_target_isize ( read_bytes, this) )
599- }
600- Err ( e) => {
601- this. set_last_error_from_io_error ( e) ?;
602- Ok ( Scalar :: from_target_isize ( -1 , this) )
603- }
604- }
586+ let res = write_byte_helper ( buf, bytes, result, this) ?;
587+ this. write_scalar ( res, dest) ?;
588+ Ok ( ( ) )
605589 }
606590
607591 fn write (
@@ -647,3 +631,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
647631 Ok ( Scalar :: from_target_isize ( this. try_unwrap_io_result ( result) ?, this) )
648632 }
649633}
634+ // TODO: move this as a free function later
635+ fn write_byte_helper < ' tcx > (
636+ buf : Pointer ,
637+ bytes : Vec < u8 > ,
638+ result : InterpResult < ' tcx , io:: Result < usize > > ,
639+ ecx : & mut MiriInterpCx < ' tcx > ,
640+ ) -> InterpResult < ' tcx , Scalar > {
641+ // `File::read` never returns a value larger than `count`, so this cannot fail.
642+ match result?. map ( |c| i64:: try_from ( c) . unwrap ( ) ) {
643+ // TODO: get the byte out the result, then write the ptr.
644+ // try to pass this the write_ptr inside write
645+ // Pass the pointer inside the write function.
646+ Ok ( read_bytes) => {
647+ // If reading to `bytes` did not fail, we write those bytes to the buffer.
648+ // Crucially, if fewer than `bytes.len()` bytes were read, only write
649+ // that much into the output buffer!
650+ // TODO: write to pointer here.
651+ ecx. write_bytes_ptr (
652+ buf,
653+ bytes[ ..usize:: try_from ( read_bytes) . unwrap ( ) ] . iter ( ) . copied ( ) ,
654+ ) ?;
655+ Ok ( Scalar :: from_target_isize ( read_bytes, ecx) )
656+ }
657+ Err ( e) => {
658+ ecx. set_last_error_from_io_error ( e) ?;
659+ Ok ( Scalar :: from_target_isize ( -1 , ecx) )
660+ }
661+ }
662+ }
0 commit comments