[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: cpio -m does not preserve timestamps for symlinks
From: |
Carl Edquist |
Subject: |
Re: cpio -m does not preserve timestamps for symlinks |
Date: |
Tue, 4 Feb 2020 12:05:21 -0600 (CST) |
User-agent: |
Alpine 2.21 (DEB 202 2017-01-01) |
Hi all,
It seems that for a cpio archive that contains symlinks, the timestamps
for those symlinks are not getting preserved, even with the '-m' option.
I believe I found the issue -
in copyin.c, copyin_regular_file() and copyin_device() both make calls to
set file times (if '-m' was specified), but copyin_link() does not.
I was able to fix it by adding a call to set_file_times() in copyin_link()
if retain_time_flag is set, just like is done in copyin_device(), and
additionally adding the AT_SYMLINK_NOFOLLOW flag to the utimensat() call
in fdutimens(), which does the right thing for symlinks and does not
change the behavior for non-symlinks.
Here is a patch of what I used to get it working:
https://github.com/edquist/cpio/commit/c2ccb84d5e.patch
(Patch text also pasted below.)
Would you maintainers consider applying this enhancement/fix?
Thanks..!
Carl
---
gnu/utimens.c | 2 +-
src/copyin.c | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/gnu/utimens.c b/gnu/utimens.c
index e2bb702..2e870bc 100644
--- a/gnu/utimens.c
+++ b/gnu/utimens.c
@@ -244,7 +244,7 @@ fdutimens (int fd, char const *file, struct timespec const
timespec[2])
# if HAVE_UTIMENSAT
if (fd < 0)
{
- result = utimensat (AT_FDCWD, file, ts, 0);
+ result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW);
# ifdef __linux__
/* Work around a kernel bug:
http://bugzilla.redhat.com/442352
diff --git a/src/copyin.c b/src/copyin.c
index b29f348..eb40e99 100644
--- a/src/copyin.c
+++ b/src/copyin.c
@@ -669,6 +669,9 @@ copyin_link (struct cpio_file_stat *file_hdr, int
in_file_des)
&& errno != EPERM)
chown_error_details (file_hdr->c_name, uid, gid);
}
+ if (retain_time_flag)
+ set_file_times (-1, file_hdr->c_name, file_hdr->c_mtime,
+ file_hdr->c_mtime);
free (link_name);
}