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