@@ -231,6 +231,8 @@ impl FileDescription for FileHandle {
231231 TRUE => Ok ( ( ) ) ,
232232 FALSE => {
233233 let mut err = io:: Error :: last_os_error ( ) ;
234+ // This only runs on Windows hosts so we can use `raw_os_error`.
235+ // We have to be careful not to forward that error code to target code.
234236 let code: u32 = err. raw_os_error ( ) . unwrap ( ) . try_into ( ) . unwrap ( ) ;
235237 if matches ! ( code, ERROR_IO_PENDING | ERROR_LOCK_VIOLATION ) {
236238 if lock_nb {
@@ -339,15 +341,10 @@ trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> {
339341 _ => interp_ok ( this. eval_libc ( "DT_UNKNOWN" ) . to_u8 ( ) ?. into ( ) ) ,
340342 }
341343 }
342- Err ( e) =>
343- match e. raw_os_error ( ) {
344- Some ( error) => interp_ok ( error) ,
345- None =>
346- throw_unsup_format ! (
347- "the error {} couldn't be converted to a return value" ,
348- e
349- ) ,
350- } ,
344+ Err ( _) => {
345+ // Fallback on error
346+ interp_ok ( this. eval_libc ( "DT_UNKNOWN" ) . to_u8 ( ) ?. into ( ) )
347+ }
351348 }
352349 }
353350}
@@ -1132,14 +1129,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
11321129 // Reject if isolation is enabled.
11331130 if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
11341131 this. reject_in_isolation ( "`readdir_r`" , reject_with) ?;
1135- // Set error code as "EBADF" (bad fd)
1136- return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
1132+ // Return error code, do *not* set `errno`.
1133+ return interp_ok ( this. eval_libc ( "EBADF" ) ) ;
11371134 }
11381135
11391136 let open_dir = this. machine . dirs . streams . get_mut ( & dirp) . ok_or_else ( || {
11401137 err_unsup_format ! ( "the DIR pointer passed to readdir_r did not come from opendir" )
11411138 } ) ?;
1142- interp_ok ( Scalar :: from_i32 ( match open_dir. read_dir . next ( ) {
1139+ interp_ok ( match open_dir. read_dir . next ( ) {
11431140 Some ( Ok ( dir_entry) ) => {
11441141 // Write into entry, write pointer to result, return 0 on success.
11451142 // The name is written with write_os_str_to_c_str, while the rest of the
@@ -1217,25 +1214,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
12171214 let result_place = this. deref_pointer ( result_op) ?;
12181215 this. write_scalar ( this. read_scalar ( entry_op) ?, & result_place) ?;
12191216
1220- 0
1217+ Scalar :: from_i32 ( 0 )
12211218 }
12221219 None => {
12231220 // end of stream: return 0, assign *result=NULL
12241221 this. write_null ( & this. deref_pointer ( result_op) ?) ?;
1225- 0
1222+ Scalar :: from_i32 ( 0 )
12261223 }
1227- Some ( Err ( e) ) =>
1228- match e. raw_os_error ( ) {
1229- // return positive error number on error
1230- Some ( error) => error,
1231- None => {
1232- throw_unsup_format ! (
1233- "the error {} couldn't be converted to a return value" ,
1234- e
1235- )
1236- }
1237- } ,
1238- } ) )
1224+ Some ( Err ( e) ) => {
1225+ // return positive error number on error (do *not* set last error)
1226+ this. io_error_to_errnum ( e) ?
1227+ }
1228+ } )
12391229 }
12401230
12411231 fn closedir ( & mut self , dirp_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , Scalar > {
0 commit comments