mirror of https://github.com/rust-lang/rust.git
bootstrap: fix trying to modify file times on read-only file on Windows
This commit is contained in:
parent
69e36d65f9
commit
26fae1ed1c
|
@ -703,9 +703,7 @@ download-rustc = false
|
||||||
let file_times = fs::FileTimes::new().set_accessed(now).set_modified(now);
|
let file_times = fs::FileTimes::new().set_accessed(now).set_modified(now);
|
||||||
|
|
||||||
let llvm_config = llvm_root.join("bin").join(exe("llvm-config", self.build));
|
let llvm_config = llvm_root.join("bin").join(exe("llvm-config", self.build));
|
||||||
let llvm_config_file = t!(File::options().write(true).open(llvm_config));
|
t!(crate::utils::helpers::set_file_times(llvm_config, file_times));
|
||||||
|
|
||||||
t!(llvm_config_file.set_times(file_times));
|
|
||||||
|
|
||||||
if self.should_fix_bins_and_dylibs() {
|
if self.should_fix_bins_and_dylibs() {
|
||||||
let llvm_lib = llvm_root.join("lib");
|
let llvm_lib = llvm_root.join("lib");
|
||||||
|
|
|
@ -37,7 +37,9 @@ use crate::core::builder;
|
||||||
use crate::core::builder::{Builder, Kind};
|
use crate::core::builder::{Builder, Kind};
|
||||||
use crate::core::config::{flags, DryRun, LldMode, LlvmLibunwind, Target, TargetSelection};
|
use crate::core::config::{flags, DryRun, LldMode, LlvmLibunwind, Target, TargetSelection};
|
||||||
use crate::utils::exec::{command, BehaviorOnFailure, BootstrapCommand, CommandOutput, OutputMode};
|
use crate::utils::exec::{command, BehaviorOnFailure, BootstrapCommand, CommandOutput, OutputMode};
|
||||||
use crate::utils::helpers::{self, dir_is_empty, exe, libdir, mtime, output, symlink_dir};
|
use crate::utils::helpers::{
|
||||||
|
self, dir_is_empty, exe, libdir, mtime, output, set_file_times, symlink_dir,
|
||||||
|
};
|
||||||
|
|
||||||
mod core;
|
mod core;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
@ -1792,21 +1794,20 @@ Executed at: {executed_at}"#,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Ok(()) = fs::hard_link(&src, dst) {
|
if let Ok(()) = fs::hard_link(&src, dst) {
|
||||||
// Attempt to "easy copy" by creating a hard link
|
// Attempt to "easy copy" by creating a hard link (symlinks are priviledged on windows),
|
||||||
// (symlinks don't work on windows), but if that fails
|
// but if that fails just fall back to a slow `copy` operation.
|
||||||
// just fall back to a slow `copy` operation.
|
|
||||||
} else {
|
} else {
|
||||||
if let Err(e) = fs::copy(&src, dst) {
|
if let Err(e) = fs::copy(&src, dst) {
|
||||||
panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e)
|
panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e)
|
||||||
}
|
}
|
||||||
t!(fs::set_permissions(dst, metadata.permissions()));
|
t!(fs::set_permissions(dst, metadata.permissions()));
|
||||||
|
|
||||||
|
// Restore file times because changing permissions on e.g. Linux using `chmod` can cause
|
||||||
|
// file access time to change.
|
||||||
let file_times = fs::FileTimes::new()
|
let file_times = fs::FileTimes::new()
|
||||||
.set_accessed(t!(metadata.accessed()))
|
.set_accessed(t!(metadata.accessed()))
|
||||||
.set_modified(t!(metadata.modified()));
|
.set_modified(t!(metadata.modified()));
|
||||||
|
t!(set_file_times(dst, file_times));
|
||||||
let dst_file = t!(fs::File::open(dst));
|
|
||||||
t!(dst_file.set_times(file_times));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -544,3 +544,15 @@ pub fn get_closest_merge_base_commit(
|
||||||
|
|
||||||
Ok(output_result(git.as_command_mut())?.trim().to_owned())
|
Ok(output_result(git.as_command_mut())?.trim().to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the file times for a given file at `path`.
|
||||||
|
pub fn set_file_times<P: AsRef<Path>>(path: P, times: fs::FileTimes) -> io::Result<()> {
|
||||||
|
// Windows requires file to be writable to modify file times. But on Linux CI the file does not
|
||||||
|
// need to be writable to modify file times and might be read-only.
|
||||||
|
let f = if cfg!(windows) {
|
||||||
|
fs::File::options().write(true).open(path)?
|
||||||
|
} else {
|
||||||
|
fs::File::open(path)?
|
||||||
|
};
|
||||||
|
f.set_times(times)
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::utils::helpers::{
|
use crate::utils::helpers::{
|
||||||
check_cfg_arg, extract_beta_rev, hex_encode, make, program_out_of_date, symlink_dir,
|
check_cfg_arg, extract_beta_rev, hex_encode, make, program_out_of_date, set_file_times,
|
||||||
|
symlink_dir,
|
||||||
};
|
};
|
||||||
use crate::{Config, Flags};
|
use crate::{Config, Flags};
|
||||||
|
|
||||||
|
@ -92,3 +93,25 @@ fn test_symlink_dir() {
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
fs::remove_file(link_path).unwrap();
|
fs::remove_file(link_path).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_set_file_times_sanity_check() {
|
||||||
|
let config =
|
||||||
|
Config::parse(Flags::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]));
|
||||||
|
let tempfile = config.tempdir().join(".tmp-file");
|
||||||
|
|
||||||
|
{
|
||||||
|
File::create(&tempfile).unwrap().write_all(b"dummy value").unwrap();
|
||||||
|
assert!(tempfile.exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
// This might only fail on Windows (if file is default read-only then we try to modify file
|
||||||
|
// times).
|
||||||
|
let unix_epoch = std::time::SystemTime::UNIX_EPOCH;
|
||||||
|
let target_time = fs::FileTimes::new().set_accessed(unix_epoch).set_modified(unix_epoch);
|
||||||
|
set_file_times(&tempfile, target_time).unwrap();
|
||||||
|
|
||||||
|
let found_metadata = fs::metadata(tempfile).unwrap();
|
||||||
|
assert_eq!(found_metadata.accessed().unwrap(), unix_epoch);
|
||||||
|
assert_eq!(found_metadata.modified().unwrap(), unix_epoch)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue