@@ -639,7 +639,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
639639 & mut self ,
640640 path_op : & OpTy < ' tcx > ,
641641 buf_op : & OpTy < ' tcx > ,
642- ) -> InterpResult < ' tcx , Scalar > {
642+ dest : & MPlaceTy < ' tcx > ,
643+ ) -> InterpResult < ' tcx , EmulateItemResult > {
643644 let this = self . eval_context_mut ( ) ;
644645
645646 if !matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
@@ -652,26 +653,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
652653 // Reject if isolation is enabled.
653654 if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
654655 this. reject_in_isolation ( "`stat`" , reject_with) ?;
655- let eacc = this. eval_libc ( "EACCES" ) ;
656- this. set_last_error ( eacc) ?;
657- return Ok ( Scalar :: from_i32 ( -1 ) ) ;
656+ return this. set_libc_err_and_return_neg1 ( "EACCES" , dest) ;
658657 }
659658
660659 // `stat` always follows symlinks.
661660 let metadata = match FileMetadata :: from_path ( this, & path, true ) ? {
662661 Some ( metadata) => metadata,
663- None => return Ok ( Scalar :: from_i32 ( -1 ) ) , // `FileMetadata` has set errno
662+ None => {
663+ this. write_int ( -1 , dest) ?;
664+ return Ok ( EmulateItemResult :: NeedsReturn ) ;
665+ }
664666 } ;
665-
666- Ok ( Scalar :: from_i32 ( this. macos_stat_write_buf ( metadata, buf_op) ?) )
667+ let res = this. macos_stat_write_buf ( metadata, buf_op) ?;
668+ this. write_int ( res, dest) ?;
669+ Ok ( EmulateItemResult :: NeedsReturn )
667670 }
668671
669672 // `lstat` is used to get symlink metadata.
670673 fn macos_fbsd_lstat (
671674 & mut self ,
672675 path_op : & OpTy < ' tcx > ,
673676 buf_op : & OpTy < ' tcx > ,
674- ) -> InterpResult < ' tcx , Scalar > {
677+ dest : & MPlaceTy < ' tcx > ,
678+ ) -> InterpResult < ' tcx , EmulateItemResult > {
675679 let this = self . eval_context_mut ( ) ;
676680
677681 if !matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
@@ -684,24 +688,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
684688 // Reject if isolation is enabled.
685689 if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
686690 this. reject_in_isolation ( "`lstat`" , reject_with) ?;
687- let eacc = this. eval_libc ( "EACCES" ) ;
688- this. set_last_error ( eacc) ?;
689- return Ok ( Scalar :: from_i32 ( -1 ) ) ;
691+ return this. set_libc_err_and_return_neg1 ( "EACCES" , dest) ;
690692 }
691693
692694 let metadata = match FileMetadata :: from_path ( this, & path, false ) ? {
693695 Some ( metadata) => metadata,
694- None => return Ok ( Scalar :: from_i32 ( -1 ) ) , // `FileMetadata` has set errno
696+ None => {
697+ this. write_int ( -1 , dest) ?;
698+ return Ok ( EmulateItemResult :: NeedsReturn ) ;
699+ }
695700 } ;
696-
697- Ok ( Scalar :: from_i32 ( this. macos_stat_write_buf ( metadata, buf_op) ?) )
701+ let res = this. macos_stat_write_buf ( metadata, buf_op) ?;
702+ this. write_int ( res, dest) ?;
703+ Ok ( EmulateItemResult :: NeedsReturn )
698704 }
699705
700706 fn macos_fbsd_fstat (
701707 & mut self ,
702708 fd_op : & OpTy < ' tcx > ,
703709 buf_op : & OpTy < ' tcx > ,
704- ) -> InterpResult < ' tcx , Scalar > {
710+ dest : & MPlaceTy < ' tcx > ,
711+ ) -> InterpResult < ' tcx , EmulateItemResult > {
705712 let this = self . eval_context_mut ( ) ;
706713
707714 if !matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
@@ -714,14 +721,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
714721 if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
715722 this. reject_in_isolation ( "`fstat`" , reject_with) ?;
716723 // Set error code as "EBADF" (bad fd)
717- return Ok ( Scalar :: from_i32 ( this. fd_not_found ( ) ? ) ) ;
724+ return this. set_fd_not_found_and_return_neg1 ( dest ) ;
718725 }
719726
720727 let metadata = match FileMetadata :: from_fd ( this, fd) ? {
721728 Some ( metadata) => metadata,
722- None => return Ok ( Scalar :: from_i32 ( -1 ) ) ,
729+ None => {
730+ this. write_int ( -1 , dest) ?;
731+ return Ok ( EmulateItemResult :: NeedsReturn ) ;
732+ }
723733 } ;
724- Ok ( Scalar :: from_i32 ( this. macos_stat_write_buf ( metadata, buf_op) ?) )
734+ let res = this. macos_stat_write_buf ( metadata, buf_op) ?;
735+ this. write_int ( res, dest) ?;
736+ Ok ( EmulateItemResult :: NeedsReturn )
725737 }
726738
727739 fn linux_statx (
@@ -1129,7 +1141,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
11291141 dirp_op : & OpTy < ' tcx > ,
11301142 entry_op : & OpTy < ' tcx > ,
11311143 result_op : & OpTy < ' tcx > ,
1132- ) -> InterpResult < ' tcx , Scalar > {
1144+ dest : & MPlaceTy < ' tcx > ,
1145+ ) -> InterpResult < ' tcx , EmulateItemResult > {
11331146 let this = self . eval_context_mut ( ) ;
11341147
11351148 if !matches ! ( & * this. tcx. sess. target. os, "macos" | "freebsd" ) {
@@ -1141,14 +1154,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
11411154 // Reject if isolation is enabled.
11421155 if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
11431156 this. reject_in_isolation ( "`readdir_r`" , reject_with) ?;
1144- // Set error code as "EBADF" (bad fd)
1145- return Ok ( Scalar :: from_i32 ( this. fd_not_found ( ) ?) ) ;
1157+ // TODO: why does this set the global error code and returns -1?
1158+ // at the end of this function we don't set the code, we just return it.
1159+ let i: i32 = this. fd_not_found ( ) ?;
1160+ this. write_int ( i, dest) ?;
1161+ return Ok ( EmulateItemResult :: NeedsReturn ) ;
11461162 }
11471163
11481164 let open_dir = this. machine . dirs . streams . get_mut ( & dirp) . ok_or_else ( || {
11491165 err_unsup_format ! ( "the DIR pointer passed to readdir_r did not come from opendir" )
11501166 } ) ?;
1151- Ok ( Scalar :: from_i32 ( match open_dir. read_dir . next ( ) {
1167+ match open_dir. read_dir . next ( ) {
11521168 Some ( Ok ( dir_entry) ) => {
11531169 // Write into entry, write pointer to result, return 0 on success.
11541170 // The name is written with write_os_str_to_c_str, while the rest of the
@@ -1225,26 +1241,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
12251241
12261242 let result_place = this. deref_pointer ( result_op) ?;
12271243 this. write_scalar ( this. read_scalar ( entry_op) ?, & result_place) ?;
1228-
1229- 0
1244+ this. write_null ( dest) ?;
12301245 }
12311246 None => {
12321247 // end of stream: return 0, assign *result=NULL
12331248 this. write_null ( & this. deref_pointer ( result_op) ?) ?;
1234- 0
1249+ this . write_null ( dest ) ? ;
12351250 }
12361251 Some ( Err ( e) ) =>
12371252 match e. raw_os_error ( ) {
12381253 // return positive error number on error
1239- Some ( error) => error,
1254+ Some ( error) => this . write_int ( error, dest ) ? ,
12401255 None => {
12411256 throw_unsup_format ! (
12421257 "the error {} couldn't be converted to a return value" ,
12431258 e
12441259 )
12451260 }
12461261 } ,
1247- } ) )
1262+ }
1263+
1264+ Ok ( EmulateItemResult :: NeedsReturn )
12481265 }
12491266
12501267 fn closedir ( & mut self , dirp_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , Scalar > {
0 commit comments