From 45cb9d8ec3419bbf411c8fe49639b84040fc9d23 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 19 Mar 2024 10:04:32 +0000 Subject: [PATCH 1/2] Add regression test for #107495 --- .../issue-107495-archive-permissions/foo.rs | 1 + .../issue-107495-archive-permissions/rmake.rs | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/run-make/issue-107495-archive-permissions/foo.rs create mode 100644 tests/run-make/issue-107495-archive-permissions/rmake.rs diff --git a/tests/run-make/issue-107495-archive-permissions/foo.rs b/tests/run-make/issue-107495-archive-permissions/foo.rs new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/tests/run-make/issue-107495-archive-permissions/foo.rs @@ -0,0 +1 @@ + diff --git a/tests/run-make/issue-107495-archive-permissions/rmake.rs b/tests/run-make/issue-107495-archive-permissions/rmake.rs new file mode 100644 index 0000000000000..593ba4b4ae70f --- /dev/null +++ b/tests/run-make/issue-107495-archive-permissions/rmake.rs @@ -0,0 +1,22 @@ +extern crate run_make_support; + +use run_make_support::{aux_build, out_dir}; +use std::fs; +#[cfg(unix)] +use std::os::unix::fs::PermissionsExt; +use std::path::Path; + +fn main() { + aux_build().arg("foo.rs").run(); + verify(&out_dir().join("libfoo.rlib")); +} + +fn verify(path: &Path) { + let perm = fs::metadata(path).unwrap().permissions(); + + assert!(!perm.readonly()); + + // Check that the file is readable for everyone + #[cfg(unix)] + assert_eq!(perm.mode(), 0o100664); +} From 2a805f59defa34c04206b74aaa483e8ea0b9dc93 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 19 Mar 2024 10:10:47 +0000 Subject: [PATCH 2/2] Use the default file permissions when writing static libraries with ar_archive_writer Fixes #107495 --- .../rustc_codegen_ssa/src/back/archive.rs | 37 +++++++++++-------- .../issue-107495-archive-permissions/foo.rs | 2 +- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 22b58c13949e2..bb285a3bbd02c 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -13,7 +13,7 @@ use object::read::macho::FatArch; use tempfile::Builder as TempFileBuilder; use std::error::Error; -use std::fs::File; +use std::fs::{self, File}; use std::io::{self, Write}; use std::path::{Path, PathBuf}; @@ -276,19 +276,22 @@ impl<'a> ArArchiveBuilder<'a> { // 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() + // The tempfile crate currently uses 0o600 as mode for the temporary files and directories + // it creates. We need it to be the default mode for back compat reasons however. (See + // #107495) To handle this we are telling tempfile to create a temporary directory instead + // and then inside this directory create a file using File::create. + let archive_tmpdir = 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, - )?; + .tempdir_in(output.parent().unwrap_or_else(|| Path::new(""))) + .map_err(|err| { + io_error_context("couldn't create a directory for the temp file", err) + })?; + let archive_tmpfile_path = archive_tmpdir.path().join("tmp.a"); + let mut archive_tmpfile = File::create_new(&archive_tmpfile_path) + .map_err(|err| io_error_context("couldn't create the temp file", err))?; + + write_archive_to_stream(&mut archive_tmpfile, &entries, true, archive_kind, true, false)?; + drop(archive_tmpfile); let any_entries = !entries.is_empty(); drop(entries); @@ -296,9 +299,11 @@ impl<'a> ArArchiveBuilder<'a> { // output archive to the same location as an input archive on Windows. drop(self.src_archives); - archive_tmpfile - .persist(output) - .map_err(|err| io_error_context("failed to rename archive file", err.error))?; + fs::rename(archive_tmpfile_path, output) + .map_err(|err| io_error_context("failed to rename archive file", err))?; + archive_tmpdir + .close() + .map_err(|err| io_error_context("failed to remove temporary directory", err))?; Ok(any_entries) } diff --git a/tests/run-make/issue-107495-archive-permissions/foo.rs b/tests/run-make/issue-107495-archive-permissions/foo.rs index 8b137891791fe..d15abba59766b 100644 --- a/tests/run-make/issue-107495-archive-permissions/foo.rs +++ b/tests/run-make/issue-107495-archive-permissions/foo.rs @@ -1 +1 @@ - +// Empty