And, in case it helps, from configuring the cpio-2.13 sources:
$ ./configure 2>&1 | grep utim
checking for utime.h... yes
checking for futimes... yes
checking for futimesat... yes
checking for futimens... yes
checking for utimensat... yes
checking for lutimes... yes
checking whether futimens is declared without a macro... yes
checking whether utimensat is declared without a macro... yes
checking whether the utimes function works... yes
checking for struct utimbuf... yes
checking whether futimens is declared without a macro... (cached) yes
checking whether utimensat is declared without a macro... (cached) yes
checking whether utimensat works... yes
checking for utime.h... (cached) yes
$ grep define.*UTIM config.h
#define GNULIB_TEST_UTIMENSAT 1
#define HAVE_FUTIMENS 1
#define HAVE_FUTIMES 1
#define HAVE_FUTIMESAT 1
#define HAVE_LUTIMES 1
#define HAVE_RAW_DECL_FUTIMENS 1
#define HAVE_RAW_DECL_UTIMENSAT 1
#define HAVE_STRUCT_UTIMBUF 1
#define HAVE_UTIMENSAT 1
#define HAVE_UTIME_H 1
#define HAVE_WORKING_UTIMES 1
On Mon, 3 Feb 2020, Carl Edquist wrote:
Date: Mon, 3 Feb 2020 18:48:58
From: Carl Edquist <[email protected]>
To: [email protected]
Subject: cpio -m does not preserve timestamps for symlinks
It seems that for a cpio archive that contains symlinks, the timestamps for
those symlinks are not getting preserved, even with the '-m' option.
A quick strace shows that in '-m' mode, utimensat(2) gets called for all the
regular files and directories, to restore their timestamps, but no attempt is
made to restore it for symlinks (even though utimensat(2) does allow that
with AT_SYMLINK_NOFOLLOW).
At first I was not sure if this was going to be a bug report or a feature
request, so I took a look at the latest cpio-2.13 sources.
There is an inline wrapper function called 'lutimensat' around utimensat with
AT_SYMLINK_NOFOLLOW, but it is never referenced anywhere else in the sources.
And there is a more complicated 'lutimens' function which contains some
#ifdefs to try to do the right thing as best it can to set symlink timestamps
if possible.
'lutimens' is defined in utimens.c and referenced in utimensat.c, which
includes at-func.c, which is a maze of macros that's a bit hard to follow.
So it seems that the intention in cpio is to handle setting timestamps for
symlinks. But in any case that code path does not seem to get reached for
me, even with the latest cpio-2.13. (I'm using Linux kernel 4.15.0, gcc
7.4.0, and gnu libc 2.27.)
Easy reproducer:
$ ln -s . selfie
$ touch -hd '2000-01-01 12:34:56' selfie
$ echo selfie | cpio -o > selfie.cpio
$ cpio -tv < selfie.cpio
lrwxrwxrwx 1 root root 1 Jan 1 2000 selfie -> .
$ rm selfie
$ cpio -im < selfie.cpio
$ ls -l selfie
lrwxrwxrwx 1 root root 1 Feb 3 18:10 selfie -> .
Note the timestamp of the 'selfie' symlink was not preserved.
Can the current maintainers confirm whether this might be broken?
Thanks,
Carl