@@ -233,40 +233,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
233
233
) ;
234
234
}
235
235
236
- match creation_disposition {
237
- CreateAlways | OpenAlways => {
238
- // Per the documentation:
239
- // If the specified file exists and is writable, the function truncates the file,
240
- // the function succeeds, and last-error code is set to ERROR_ALREADY_EXISTS.
241
- // If the specified file does not exist and is a valid path, a new file is created,
242
- // the function succeeds, and the last-error code is set to zero.
243
- // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
244
- //
245
- // This is racy, but there doesn't appear to be an std API that both succeeds if a
246
- // file exists but tells us it isn't new. Either we accept racing one way or another,
247
- // or we use an iffy heuristic like file creation time. This implementation prefers
248
- // to fail in the direction of erroring more often.
249
- if file_name. exists ( ) {
250
- this. set_last_error ( IoError :: WindowsError ( "ERROR_ALREADY_EXISTS" ) ) ?;
251
- }
252
- options. create ( true ) ;
253
- if creation_disposition == CreateAlways {
254
- options. truncate ( true ) ;
255
- }
256
- }
257
- CreateNew => {
258
- options. create_new ( true ) ;
259
- // Per `create_new` documentation:
260
- // The file must be opened with write or append access in order to create a new file.
261
- // https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.create_new
262
- if !desired_write {
263
- options. append ( true ) ;
264
- }
265
- }
266
- OpenExisting => { } // Default options
267
- TruncateExisting => {
268
- options. truncate ( true ) ;
269
- }
236
+ // Per the documentation:
237
+ // If the specified file exists and is writable, the function truncates the file,
238
+ // the function succeeds, and last-error code is set to ERROR_ALREADY_EXISTS.
239
+ // If the specified file does not exist and is a valid path, a new file is created,
240
+ // the function succeeds, and the last-error code is set to zero.
241
+ // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
242
+ //
243
+ // This is racy, but there doesn't appear to be an std API that both succeeds if a
244
+ // file exists but tells us it isn't new. Either we accept racing one way or another,
245
+ // or we use an iffy heuristic like file creation time. This implementation prefers
246
+ // to fail in the direction of erroring more often.
247
+ if let CreateAlways | OpenAlways = creation_disposition
248
+ && file_name. exists ( )
249
+ {
250
+ this. set_last_error ( IoError :: WindowsError ( "ERROR_ALREADY_EXISTS" ) ) ?;
270
251
}
271
252
272
253
let handle = if is_dir {
@@ -282,6 +263,28 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
282
263
Handle :: File ( fd_num)
283
264
} )
284
265
} else {
266
+ match creation_disposition {
267
+ CreateAlways | OpenAlways => {
268
+ options. create ( true ) ;
269
+ if creation_disposition == CreateAlways {
270
+ options. truncate ( true ) ;
271
+ }
272
+ }
273
+ CreateNew => {
274
+ options. create_new ( true ) ;
275
+ // Per `create_new` documentation:
276
+ // The file must be opened with write or append access in order to create a new file.
277
+ // https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.create_new
278
+ if !desired_write {
279
+ options. append ( true ) ;
280
+ }
281
+ }
282
+ OpenExisting => { } // Default options
283
+ TruncateExisting => {
284
+ options. truncate ( true ) ;
285
+ }
286
+ }
287
+
285
288
options. open ( file_name) . map ( |file| {
286
289
let fh = & mut this. machine . fds ;
287
290
let fd_num = fh. insert_new ( FileHandle { file, writable : desired_write } ) ;
0 commit comments