@@ -361,14 +361,34 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
361361 }
362362
363363 /// 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.
365365 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)
372392 }
373393
374394 /// Helper function that consumes an `std::io::Result<T>` and returns an
0 commit comments