Skip to content

Commit

Permalink
Auto merge of #2386 - RalfJung:xargo-atomic, r=RalfJung
Browse files Browse the repository at this point in the history
cargo-miri: write the Xargo project files atomically

`@matthiaskrgr` this should fix #2340. Any chance you could test this before we land it?
  • Loading branch information
bors committed Jul 19, 2022
2 parents eb7ea4c + 56fefe1 commit 5bd59c8
Showing 1 changed file with 30 additions and 17 deletions.
47 changes: 30 additions & 17 deletions cargo-miri/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,23 @@ fn ask_to_run(mut cmd: Command, ask: bool, text: &str) {
}
}

/// Writes the given content to the given file *cross-process atomically*, in the sense that another
/// process concurrently reading that file will see either the old content or the new content, but
/// not some intermediate (e.g., empty) state.
///
/// We assume no other parts of this same process are trying to read or write that file.
fn write_to_file(filename: &Path, content: &str) {
// Create a temporary file with the desired contents.
let mut temp_filename = filename.as_os_str().to_os_string();
temp_filename.push(&format!(".{}", std::process::id()));
let mut temp_file = File::create(&temp_filename).unwrap();
temp_file.write_all(content.as_bytes()).unwrap();
drop(temp_file);

// Move file to the desired location.
fs::rename(temp_filename, filename).unwrap();
}

/// Performs the setup required to make `cargo miri` work: Getting a custom-built libstd. Then sets
/// `MIRI_SYSROOT`. Skipped if `MIRI_SYSROOT` is already set, in which case we expect the user has
/// done all this already.
Expand Down Expand Up @@ -398,28 +415,25 @@ fn setup(subcommand: MiriCommand) {
if !dir.exists() {
fs::create_dir_all(&dir).unwrap();
}
let mut xargo_toml = File::create(dir.join("Xargo.toml")).unwrap();
if std::env::var_os("MIRI_NO_STD").is_none() {
// The interesting bit: Xargo.toml (only needs content if we actually need std)
xargo_toml
.write_all(
br#"
// The interesting bit: Xargo.toml (only needs content if we actually need std)
let xargo_toml = if std::env::var_os("MIRI_NO_STD").is_some() {
""
} else {
r#"
[dependencies.std]
default_features = false
# We support unwinding, so enable that panic runtime.
features = ["panic_unwind", "backtrace"]
[dependencies.test]
"#,
)
.unwrap();
}
"#
};
write_to_file(&dir.join("Xargo.toml"), xargo_toml);
// The boring bits: a dummy project for xargo.
// FIXME: With xargo-check, can we avoid doing this?
File::create(dir.join("Cargo.toml"))
.unwrap()
.write_all(
br#"
write_to_file(
&dir.join("Cargo.toml"),
r#"
[package]
name = "miri-xargo"
description = "A dummy project for building libstd with xargo."
Expand All @@ -428,9 +442,8 @@ version = "0.0.0"
[lib]
path = "lib.rs"
"#,
)
.unwrap();
File::create(dir.join("lib.rs")).unwrap().write_all(b"#![no_std]").unwrap();
);
write_to_file(&dir.join("lib.rs"), "#![no_std]");

// Determine architectures.
// We always need to set a target so rustc bootstrap can tell apart host from target crates.
Expand Down

0 comments on commit 5bd59c8

Please sign in to comment.