Skip to content

Commit

Permalink
Use the default file permissions when writing
Browse files Browse the repository at this point in the history
static libraries with ar_archive_writer

Fixes #107495
  • Loading branch information
bjorn3 committed Mar 22, 2024
1 parent 45cb9d8 commit 5b8677e
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 17 deletions.
37 changes: 21 additions & 16 deletions compiler/rustc_codegen_ssa/src/back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -276,29 +276,34 @@ 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);
// Drop src_archives to unmap all input archives, which is necessary if we want to write the
// 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)
}
Expand Down
2 changes: 1 addition & 1 deletion tests/run-make/issue-107495-archive-permissions/foo.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@

// Empty
10 changes: 10 additions & 0 deletions tests/run-make/issue-107495-archive-permissions/rmake.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#![feature(rustc_private)]

#[cfg(unix)]
extern crate libc;
extern crate run_make_support;

use run_make_support::{aux_build, out_dir};
Expand All @@ -7,7 +11,13 @@ use std::os::unix::fs::PermissionsExt;
use std::path::Path;

fn main() {
#[cfg(unix)]
unsafe {
libc::umask(0o002);
}

aux_build().arg("foo.rs").run();

verify(&out_dir().join("libfoo.rlib"));
}

Expand Down

0 comments on commit 5b8677e

Please sign in to comment.