Skip to content

Commit

Permalink
Preserve symlink mtimes (#289)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrwats authored Apr 4, 2022
1 parent c3e2cb8 commit f4f439c
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 10 deletions.
32 changes: 22 additions & 10 deletions src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,19 @@ impl<'a> EntryFields<'a> {
Ok(())
}

fn get_mtime(header: &Header) -> Option<FileTime> {
header.mtime().ok().map(|mtime| {
// For some more information on this see the comments in
// `Header::fill_platform_from`, but the general idea is that
// we're trying to avoid 0-mtime files coming out of archives
// since some tools don't ingest them well. Perhaps one day
// when Cargo stops working with 0-mtime archives we can remove
// this.
let mtime = if mtime == 0 { 1 } else { mtime };
FileTime::from_unix_time(mtime as i64, 0)
})
}

let kind = self.header.entry_type();

if kind.is_dir() {
Expand Down Expand Up @@ -546,7 +559,14 @@ impl<'a> EntryFields<'a> {
),
)
})?;
};
if self.preserve_mtime {
if let Some(mtime) = get_mtime(&self.header) {
filetime::set_symlink_file_times(dst, mtime, mtime).map_err(|e| {
TarError::new(format!("failed to set mtime for `{}`", dst.display()), e)
})?;
}
}
}
return Ok(Unpacked::__Nonexhaustive);

#[cfg(target_arch = "wasm32")]
Expand Down Expand Up @@ -646,15 +666,7 @@ impl<'a> EntryFields<'a> {
})?;

if self.preserve_mtime {
if let Ok(mtime) = self.header.mtime() {
// For some more information on this see the comments in
// `Header::fill_platform_from`, but the general idea is that
// we're trying to avoid 0-mtime files coming out of archives
// since some tools don't ingest them well. Perhaps one day
// when Cargo stops working with 0-mtime archives we can remove
// this.
let mtime = if mtime == 0 { 1 } else { mtime };
let mtime = FileTime::from_unix_time(mtime as i64, 0);
if let Some(mtime) = get_mtime(&self.header) {
filetime::set_file_handle_times(&f, Some(mtime), Some(mtime)).map_err(|e| {
TarError::new(format!("failed to set mtime for `{}`", dst.display()), e)
})?;
Expand Down
4 changes: 4 additions & 0 deletions tests/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,10 @@ fn unpack_links() {

let md = t!(fs::symlink_metadata(td.path().join("lnk")));
assert!(md.file_type().is_symlink());

let mtime = FileTime::from_last_modification_time(&md);
assert_eq!(mtime.unix_seconds(), 1448291033);

assert_eq!(
&*t!(fs::read_link(td.path().join("lnk"))),
Path::new("file")
Expand Down

0 comments on commit f4f439c

Please sign in to comment.