Skip to content

Commit

Permalink
Write to temp file before renaming to the final name
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Dec 2, 2022
1 parent 0673cde commit e1edc13
Showing 1 changed file with 22 additions and 4 deletions.
26 changes: 22 additions & 4 deletions compiler/rustc_codegen_ssa/src/back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub use ar_archive_writer::get_native_object_symbols;
use ar_archive_writer::{write_archive_to_stream, ArchiveKind, NewArchiveMember};
use object::read::archive::ArchiveFile;
use object::read::macho::FatArch;
use tempfile::Builder as TempFileBuilder;

use std::error::Error;
use std::fs::File;
Expand Down Expand Up @@ -271,10 +272,27 @@ impl<'a> ArArchiveBuilder<'a> {
})
}

let mut w = File::create(output)
.map_err(|err| io_error_context("failed to create archive file", err))?;

write_archive_to_stream(&mut w, &entries, true, archive_kind, true, false)?;
// Write to a temporary file first before atomically renaming to the final name.
// This prevents programs (including rustc) from attempting to read a partial archive.
// It also enables writing an archive with the same filename as a dependency on Windows as
// required by a test.
let mut archive_tmpfile = TempFileBuilder::new()
.suffix(".temp-archive")
.tempfile_in(output.parent().unwrap_or_else(|| Path::new("")))
.map_err(|err| io_error_context("couldn't create a temp file", err))?;

write_archive_to_stream(
archive_tmpfile.as_file_mut(),
&entries,
true,
archive_kind,
true,
false,
)?;

archive_tmpfile
.persist(output)
.map_err(|err| io_error_context("failed to rename archive file", err.error))?;

Ok(!entries.is_empty())
}
Expand Down

0 comments on commit e1edc13

Please sign in to comment.