bug-cpio
[Top][All Lists]
Advanced

[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);
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]