@@ -319,6 +319,23 @@ fn ask_to_run(mut cmd: Command, ask: bool, text: &str) {
319
319
}
320
320
}
321
321
322
+ /// Writes the given content to the given file *cross-process atomically*, in the sense that another
323
+ /// process concurrently reading that file will see either the old content or the new content, but
324
+ /// not some intermediate (e.g., empty) state.
325
+ ///
326
+ /// We assume no other parts of this same process are trying to read or write that file.
327
+ fn write_to_file ( filename : & Path , content : & str ) {
328
+ // Create a temporary file with the desired contents.
329
+ let mut temp_filename = filename. as_os_str ( ) . to_os_string ( ) ;
330
+ temp_filename. push ( & format ! ( ".{}" , std:: process:: id( ) ) ) ;
331
+ let mut temp_file = File :: create ( & temp_filename) . unwrap ( ) ;
332
+ temp_file. write_all ( content. as_bytes ( ) ) . unwrap ( ) ;
333
+ drop ( temp_file) ;
334
+
335
+ // Move file to the desired location.
336
+ fs:: rename ( temp_filename, filename) . unwrap ( ) ;
337
+ }
338
+
322
339
/// Performs the setup required to make `cargo miri` work: Getting a custom-built libstd. Then sets
323
340
/// `MIRI_SYSROOT`. Skipped if `MIRI_SYSROOT` is already set, in which case we expect the user has
324
341
/// done all this already.
@@ -398,28 +415,25 @@ fn setup(subcommand: MiriCommand) {
398
415
if !dir. exists ( ) {
399
416
fs:: create_dir_all ( & dir) . unwrap ( ) ;
400
417
}
401
- let mut xargo_toml = File :: create ( dir. join ( "Xargo.toml" ) ) . unwrap ( ) ;
402
- if std:: env:: var_os ( "MIRI_NO_STD" ) . is_none ( ) {
403
- // The interesting bit: Xargo.toml (only needs content if we actually need std)
404
- xargo_toml
405
- . write_all (
406
- br#"
418
+ // The interesting bit: Xargo.toml (only needs content if we actually need std)
419
+ let xargo_toml = if std:: env:: var_os ( "MIRI_NO_STD" ) . is_some ( ) {
420
+ ""
421
+ } else {
422
+ r#"
407
423
[dependencies.std]
408
424
default_features = false
409
425
# We support unwinding, so enable that panic runtime.
410
426
features = ["panic_unwind", "backtrace"]
411
427
412
428
[dependencies.test]
413
- "# ,
414
- )
415
- . unwrap ( ) ;
416
- }
429
+ "#
430
+ } ;
431
+ write_to_file ( & dir. join ( "Xargo.toml" ) , xargo_toml) ;
417
432
// The boring bits: a dummy project for xargo.
418
433
// FIXME: With xargo-check, can we avoid doing this?
419
- File :: create ( dir. join ( "Cargo.toml" ) )
420
- . unwrap ( )
421
- . write_all (
422
- br#"
434
+ write_to_file (
435
+ & dir. join ( "Cargo.toml" ) ,
436
+ r#"
423
437
[package]
424
438
name = "miri-xargo"
425
439
description = "A dummy project for building libstd with xargo."
@@ -428,9 +442,8 @@ version = "0.0.0"
428
442
[lib]
429
443
path = "lib.rs"
430
444
"# ,
431
- )
432
- . unwrap ( ) ;
433
- File :: create ( dir. join ( "lib.rs" ) ) . unwrap ( ) . write_all ( b"#![no_std]" ) . unwrap ( ) ;
445
+ ) ;
446
+ write_to_file ( & dir. join ( "lib.rs" ) , "#![no_std]" ) ;
434
447
435
448
// Determine architectures.
436
449
// We always need to set a target so rustc bootstrap can tell apart host from target crates.
0 commit comments