@@ -364,14 +364,34 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
364
364
}
365
365
366
366
/// Sets the last error variable using a `std::io::Error`. It fails if the error cannot be
367
- /// transformed to a raw os error succesfully
367
+ /// transformed to a raw os error succesfully.
368
368
fn set_last_error_from_io_error ( & mut self , e : std:: io:: Error ) -> InterpResult < ' tcx > {
369
- self . eval_context_mut ( ) . set_last_error ( Scalar :: from_int (
370
- e. raw_os_error ( ) . ok_or_else ( || {
371
- err_unsup_format ! ( "The {} error cannot be transformed into a raw os error" , e)
372
- } ) ?,
373
- Size :: from_bits ( 32 ) ,
374
- ) )
369
+ use std:: io:: ErrorKind :: * ;
370
+ let this = self . eval_context_mut ( ) ;
371
+ let target = & this. tcx . tcx . sess . target . target ;
372
+ let last_error = if target. options . target_family == Some ( "unix" . to_owned ( ) ) {
373
+ this. eval_libc ( match e. kind ( ) {
374
+ ConnectionRefused => "ECONNREFUSED" ,
375
+ ConnectionReset => "ECONNRESET" ,
376
+ PermissionDenied => "EPERM" ,
377
+ BrokenPipe => "EPIPE" ,
378
+ NotConnected => "ENOTCONN" ,
379
+ ConnectionAborted => "ECONNABORTED" ,
380
+ AddrNotAvailable => "EADDRNOTAVAIL" ,
381
+ AddrInUse => "EADDRINUSE" ,
382
+ NotFound => "ENOENT" ,
383
+ Interrupted => "EINTR" ,
384
+ InvalidInput => "EINVAL" ,
385
+ TimedOut => "ETIMEDOUT" ,
386
+ AlreadyExists => "EEXIST" ,
387
+ WouldBlock => "EWOULDBLOCK" ,
388
+ _ => throw_unsup_format ! ( "The {} error cannot be transformed into a raw os error" , e)
389
+ } ) ?
390
+ } else {
391
+ // FIXME: we have to implement the windows' equivalent of this.
392
+ throw_unsup_format ! ( "Setting the last OS error from an io::Error is unsupported for {}." , target. target_os)
393
+ } ;
394
+ this. set_last_error ( last_error)
375
395
}
376
396
377
397
/// Helper function that consumes an `std::io::Result<T>` and returns an
0 commit comments