@@ -231,6 +231,8 @@ impl FileDescription for FileHandle {
231
231
TRUE => Ok ( ( ) ) ,
232
232
FALSE => {
233
233
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.
234
236
let code: u32 = err. raw_os_error ( ) . unwrap ( ) . try_into ( ) . unwrap ( ) ;
235
237
if matches ! ( code, ERROR_IO_PENDING | ERROR_LOCK_VIOLATION ) {
236
238
if lock_nb {
@@ -339,15 +341,10 @@ trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> {
339
341
_ => interp_ok ( this. eval_libc ( "DT_UNKNOWN" ) . to_u8 ( ) ?. into ( ) ) ,
340
342
}
341
343
}
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
+ }
351
348
}
352
349
}
353
350
}
@@ -1132,14 +1129,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
1132
1129
// Reject if isolation is enabled.
1133
1130
if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1134
1131
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" ) ) ;
1137
1134
}
1138
1135
1139
1136
let open_dir = this. machine . dirs . streams . get_mut ( & dirp) . ok_or_else ( || {
1140
1137
err_unsup_format ! ( "the DIR pointer passed to readdir_r did not come from opendir" )
1141
1138
} ) ?;
1142
- interp_ok ( Scalar :: from_i32 ( match open_dir. read_dir . next ( ) {
1139
+ interp_ok ( match open_dir. read_dir . next ( ) {
1143
1140
Some ( Ok ( dir_entry) ) => {
1144
1141
// Write into entry, write pointer to result, return 0 on success.
1145
1142
// 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> {
1217
1214
let result_place = this. deref_pointer ( result_op) ?;
1218
1215
this. write_scalar ( this. read_scalar ( entry_op) ?, & result_place) ?;
1219
1216
1220
- 0
1217
+ Scalar :: from_i32 ( 0 )
1221
1218
}
1222
1219
None => {
1223
1220
// end of stream: return 0, assign *result=NULL
1224
1221
this. write_null ( & this. deref_pointer ( result_op) ?) ?;
1225
- 0
1222
+ Scalar :: from_i32 ( 0 )
1226
1223
}
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
+ } )
1239
1229
}
1240
1230
1241
1231
fn closedir ( & mut self , dirp_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , Scalar > {
0 commit comments