@@ -2,6 +2,34 @@ use std::io;
2
2
3
3
use crate :: * ;
4
4
5
+ /// A representation of an IO error: either a libc error name,
6
+ /// or a host error.
7
+ #[ derive( Debug ) ]
8
+ pub enum IoError {
9
+ LibcError ( & ' static str ) ,
10
+ HostError ( io:: Error ) ,
11
+ Raw ( Scalar ) ,
12
+ }
13
+ pub use self :: IoError :: * ;
14
+
15
+ impl From < io:: Error > for IoError {
16
+ fn from ( value : io:: Error ) -> Self {
17
+ IoError :: HostError ( value)
18
+ }
19
+ }
20
+
21
+ impl From < io:: ErrorKind > for IoError {
22
+ fn from ( value : io:: ErrorKind ) -> Self {
23
+ IoError :: HostError ( value. into ( ) )
24
+ }
25
+ }
26
+
27
+ impl From < Scalar > for IoError {
28
+ fn from ( value : Scalar ) -> Self {
29
+ IoError :: Raw ( value)
30
+ }
31
+ }
32
+
5
33
// This mapping should match `decode_error_kind` in
6
34
// <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/pal/unix/mod.rs>.
7
35
const UNIX_IO_ERROR_TABLE : & [ ( & str , std:: io:: ErrorKind ) ] = {
@@ -80,10 +108,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
80
108
}
81
109
82
110
/// Sets the last error variable.
83
- fn set_last_error ( & mut self , scalar : Scalar ) -> InterpResult < ' tcx > {
111
+ fn set_last_error ( & mut self , err : impl Into < IoError > ) -> InterpResult < ' tcx > {
84
112
let this = self . eval_context_mut ( ) ;
113
+ let errno = match err. into ( ) {
114
+ HostError ( err) => this. io_error_to_errnum ( err) ?,
115
+ LibcError ( name) => this. eval_libc ( name) ,
116
+ Raw ( val) => val,
117
+ } ;
85
118
let errno_place = this. last_error_place ( ) ?;
86
- this. write_scalar ( scalar , & errno_place)
119
+ this. write_scalar ( errno , & errno_place)
87
120
}
88
121
89
122
/// Gets the last error variable.
@@ -152,19 +185,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
152
185
}
153
186
}
154
187
155
- /// Sets the last OS error using a `std::io::ErrorKind`.
156
- fn set_last_error_from_io_error ( & mut self , err : std:: io:: Error ) -> InterpResult < ' tcx > {
157
- self . set_last_error ( self . io_error_to_errnum ( err) ?)
158
- }
159
-
160
188
/// Sets the last OS error using a `std::io::ErrorKind` and writes -1 to dest place.
161
189
fn set_last_error_and_return (
162
190
& mut self ,
163
- err : impl Into < io :: Error > ,
191
+ err : impl Into < IoError > ,
164
192
dest : & MPlaceTy < ' tcx > ,
165
193
) -> InterpResult < ' tcx > {
166
194
let this = self . eval_context_mut ( ) ;
167
- this. set_last_error ( this . io_error_to_errnum ( err. into ( ) ) ? ) ?;
195
+ this. set_last_error ( err) ?;
168
196
this. write_int ( -1 , dest) ?;
169
197
Ok ( ( ) )
170
198
}
@@ -182,7 +210,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
182
210
match result {
183
211
Ok ( ok) => Ok ( ok) ,
184
212
Err ( e) => {
185
- self . eval_context_mut ( ) . set_last_error_from_io_error ( e) ?;
213
+ self . eval_context_mut ( ) . set_last_error ( e) ?;
186
214
Ok ( ( -1 ) . into ( ) )
187
215
}
188
216
}
0 commit comments