Skip to content

Commit e1edc13

Browse files
committed
Write to temp file before renaming to the final name
1 parent 0673cde commit e1edc13

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

compiler/rustc_codegen_ssa/src/back/archive.rs

+22-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub use ar_archive_writer::get_native_object_symbols;
1010
use ar_archive_writer::{write_archive_to_stream, ArchiveKind, NewArchiveMember};
1111
use object::read::archive::ArchiveFile;
1212
use object::read::macho::FatArch;
13+
use tempfile::Builder as TempFileBuilder;
1314

1415
use std::error::Error;
1516
use std::fs::File;
@@ -271,10 +272,27 @@ impl<'a> ArArchiveBuilder<'a> {
271272
})
272273
}
273274

274-
let mut w = File::create(output)
275-
.map_err(|err| io_error_context("failed to create archive file", err))?;
276-
277-
write_archive_to_stream(&mut w, &entries, true, archive_kind, true, false)?;
275+
// Write to a temporary file first before atomically renaming to the final name.
276+
// This prevents programs (including rustc) from attempting to read a partial archive.
277+
// It also enables writing an archive with the same filename as a dependency on Windows as
278+
// required by a test.
279+
let mut archive_tmpfile = TempFileBuilder::new()
280+
.suffix(".temp-archive")
281+
.tempfile_in(output.parent().unwrap_or_else(|| Path::new("")))
282+
.map_err(|err| io_error_context("couldn't create a temp file", err))?;
283+
284+
write_archive_to_stream(
285+
archive_tmpfile.as_file_mut(),
286+
&entries,
287+
true,
288+
archive_kind,
289+
true,
290+
false,
291+
)?;
292+
293+
archive_tmpfile
294+
.persist(output)
295+
.map_err(|err| io_error_context("failed to rename archive file", err.error))?;
278296

279297
Ok(!entries.is_empty())
280298
}

0 commit comments

Comments
 (0)