Skip to content

Commit 297fceb

Browse files
committed
Use the default file permissions when writing
static libraries with ar_archive_writer Fixes #107495
1 parent 66a73f0 commit 297fceb

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

compiler/rustc_codegen_ssa/src/back/archive.rs

+19-8
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use object::read::macho::FatArch;
1313
use tempfile::Builder as TempFileBuilder;
1414

1515
use std::error::Error;
16-
use std::fs::File;
16+
use std::fs::{self, File};
1717
use std::io::{self, Write};
1818
use std::path::{Path, PathBuf};
1919

@@ -280,22 +280,33 @@ impl<'a> ArArchiveBuilder<'a> {
280280
// This prevents programs (including rustc) from attempting to read a partial archive.
281281
// It also enables writing an archive with the same filename as a dependency on Windows as
282282
// required by a test.
283-
let mut archive_tmpfile = TempFileBuilder::new()
283+
// The tempfile crate currently uses 0o600 as mode for the temporary files and directories
284+
// it creates. We need it to be the default mode for back compat reasons however. (See
285+
// #107495) To handle this we are telling tempfile to create a temporary directory instead
286+
// and then inside this directory create a file using File::create.
287+
let archive_tmpdir = TempFileBuilder::new()
284288
.suffix(".temp-archive")
285-
.tempfile_in(output.parent().unwrap_or_else(|| Path::new("")))
286-
.map_err(|err| io_error_context("couldn't create a temp file", err))?;
289+
.tempdir_in(output.parent().unwrap_or_else(|| Path::new("")))
290+
.map_err(|err| {
291+
io_error_context("couldn't create a directory for the temp file", err)
292+
})?;
293+
let archive_tmpfile_path = archive_tmpdir.path().join("tmp.a");
294+
let mut archive_tmpfile = File::create_new(&archive_tmpfile_path)
295+
.map_err(|err| io_error_context("couldn't create the temp file", err))?;
287296

288-
write_archive_to_stream(archive_tmpfile.as_file_mut(), &entries, archive_kind, false)?;
297+
write_archive_to_stream(&mut archive_tmpfile, &entries, archive_kind, false)?;
289298

290299
let any_entries = !entries.is_empty();
291300
drop(entries);
292301
// Drop src_archives to unmap all input archives, which is necessary if we want to write the
293302
// output archive to the same location as an input archive on Windows.
294303
drop(self.src_archives);
295304

296-
archive_tmpfile
297-
.persist(output)
298-
.map_err(|err| io_error_context("failed to rename archive file", err.error))?;
305+
fs::rename(archive_tmpfile_path, output)
306+
.map_err(|err| io_error_context("failed to rename archive file", err))?;
307+
archive_tmpdir
308+
.close()
309+
.map_err(|err| io_error_context("failed to remove temporary directory", err))?;
299310

300311
Ok(any_entries)
301312
}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1+
// Empty

tests/run-make/issue-107495-archive-permissions/rmake.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#![feature(rustc_private)]
2+
3+
#[cfg(unix)]
4+
extern crate libc;
15
extern crate run_make_support;
26

37
use run_make_support::{aux_build, tmp_dir};
@@ -7,6 +11,11 @@ use std::os::unix::fs::PermissionsExt;
711
use std::path::Path;
812

913
fn main() {
14+
#[cfg(unix)]
15+
unsafe {
16+
libc::umask(0o002);
17+
}
18+
1019
aux_build().arg("foo.rs").run();
1120
verify(&tmp_dir().join("libfoo.rlib"));
1221
}

0 commit comments

Comments
 (0)