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