From 991f5062481d9b31e468273b76b27b8e14ad2c0a Mon Sep 17 00:00:00 2001 From: "Ricardo M. Correia" Date: Sat, 27 Sep 2014 05:08:41 +0200 Subject: [PATCH] rustc: Fix permission denied error in 'ar' when lto is enabled The reason that 'ar' can fail with permission denied is that when link-time optimizations are enabled, rustc copies libraries into a temporary directory, preserving file permissions, and subsequently modifies them using 'ar'. The modification can fail because some package managers may install libraries in system directories as read-only files, which means the temporary file also becomes read-only when it is copied. I have fixed this by giving the temporary file's owner read+write permissions after the copy. I have also added a regression test for this issue. --- src/librustc/back/link.rs | 12 ++++++++++++ src/test/run-make/lto-readonly-lib/Makefile | 12 ++++++++++++ src/test/run-make/lto-readonly-lib/lib.rs | 11 +++++++++++ src/test/run-make/lto-readonly-lib/main.rs | 13 +++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 src/test/run-make/lto-readonly-lib/Makefile create mode 100644 src/test/run-make/lto-readonly-lib/lib.rs create mode 100644 src/test/run-make/lto-readonly-lib/main.rs diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 633248562a5..b793096b30a 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -1319,6 +1319,18 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session, sess.abort_if_errors(); } } + // Fix up permissions of the copy, as fs::copy() preserves + // permissions, but the original file may have been installed + // by a package manager and may be read-only. + match fs::chmod(&dst, io::UserRead | io::UserWrite) { + Ok(..) => {} + Err(e) => { + sess.err(format!("failed to chmod {} when preparing \ + for LTO: {}", dst.display(), + e).as_slice()); + sess.abort_if_errors(); + } + } let handler = &sess.diagnostic().handler; let config = ArchiveConfig { handler: handler, diff --git a/src/test/run-make/lto-readonly-lib/Makefile b/src/test/run-make/lto-readonly-lib/Makefile new file mode 100644 index 00000000000..0afbbc3450a --- /dev/null +++ b/src/test/run-make/lto-readonly-lib/Makefile @@ -0,0 +1,12 @@ +-include ../tools.mk + +all: + $(RUSTC) lib.rs + + # the compiler needs to copy and modify the rlib file when performing + # LTO, so we should ensure that it can cope with the original rlib + # being read-only. + chmod 444 $(TMPDIR)/*.rlib + + $(RUSTC) main.rs -C lto + $(call RUN,main) diff --git a/src/test/run-make/lto-readonly-lib/lib.rs b/src/test/run-make/lto-readonly-lib/lib.rs new file mode 100644 index 00000000000..04d3ae67207 --- /dev/null +++ b/src/test/run-make/lto-readonly-lib/lib.rs @@ -0,0 +1,11 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] diff --git a/src/test/run-make/lto-readonly-lib/main.rs b/src/test/run-make/lto-readonly-lib/main.rs new file mode 100644 index 00000000000..e12ac9e01dc --- /dev/null +++ b/src/test/run-make/lto-readonly-lib/main.rs @@ -0,0 +1,13 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate lib; + +fn main() {}