@@ -364,14 +364,34 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
364364 }
365365
366366 /// 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.
368368 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)
375395 }
376396
377397 /// Helper function that consumes an `std::io::Result<T>` and returns an
0 commit comments