On 12/12/2013 06:44 PM, Pádraig Brady wrote: > On 12/09/2013 02:24 AM, Pádraig Brady wrote: >> Sorry if you get multiple copies of this. >> >> The test for this is failing on solaris 10 (NFS) >> It does seem that hardlinks to symlinks are supported: >> >> $ touch tfile >> $ ln -s tfile tlink >> $ src/ln -L tlink tlink-ln-L >> $ src/ln -P tlink tlink-ln-P >> $ src/ln tlink tlink-ln >> $ ls -li tfile tlink* >> 8550 -rw-r--r-- 3 padraig csw 0 Dec 9 01:18 tfile >> 8551 lrwxrwxrwx 2 padraig csw 5 Dec 9 01:19 tlink -> >> tfile >> 8550 -rw-r--r-- 3 padraig csw 0 Dec 9 01:18 tlink-ln >> 8550 -rw-r--r-- 3 padraig csw 0 Dec 9 01:18 tlink-ln-L >> 8551 lrwxrwxrwx 2 padraig csw 5 Dec 9 01:19 tlink-ln-P >> -> tfile >> >> But we have linkat() emulation in place I think: >> >> $ grep LINK lib/config.h > ... >> /* #undef HAVE_LINKAT */ >> #define LINK_FOLLOWS_SYMLINKS -1 > >> FAIL: tests/cp/link-deref >> ========================= > >> --- exp Mon Dec 9 01:00:08 2013 >> +++ out Mon Dec 9 01:00:08 2013 >> @@ -1,1 +1,1 @@ >> -cp --link -P dirlink dst|result=0|inode=8436|type=symbolic link|error= >> +cp --link -P dirlink dst|result=0|inode=8467|type=symbolic link|error= >> + rm -f diff.out >> + false >> + ls -lid dirlink dir dst >> 8434 drwxr-xr-x 2 padraig csw 2 Dec 9 01:00 dir >> 8436 lrwxrwxrwx 1 padraig csw 3 Dec 9 01:00 dirlink -> dir >> 8467 lrwxrwxrwx 1 padraig csw 3 Dec 9 01:00 dst -> dir >> + fail=1 > > So the attached should address this on FreeBSD ast least > where we HAVE_LINKAT so don't need to fallback to > the symlink -> symlink emulation in copy.c
I still think this is correct, and while I didn't think it worth the small risk right before the 8.22 release, I hope to push this rebased patch soon. thanks, Pádraig.
>From 1893578fb0cdbb1875a42bc86cad452f6c62e5dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]> Date: Thu, 12 Dec 2013 18:31:48 +0000 Subject: [PATCH] cp: with --link always use linkat() if available * src/copy.c (copy_reg): If linkat() is available it doesn't matter about the gnulib emulation provided, and thus the LINK_FOLLOWS_SYMLINKS should not have significance here. This was noticed on FreeBSD and the consequence is that cp --link will create hardlinks to symlinks there, rather than emulating with symlinks to symlinks. * tests/cp/link-deref.sh: Adjust to remove the no longer significant LINK_FOLLOWS_SYMLINKS check. --- src/copy.c | 10 ++++++++-- tests/cp/link-deref.sh | 3 +-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/copy.c b/src/copy.c index 3e4cbff..d560dfd 100644 --- a/src/copy.c +++ b/src/copy.c @@ -2492,8 +2492,11 @@ copy_internal (char const *src_name, char const *dst_name, timestamps or ownership so we only call it when we know the emulation will not be needed. */ else if (x->hard_link +#if ! defined HAVE_LINKAT && !(LINK_FOLLOWS_SYMLINKS && S_ISLNK (src_mode) - && x->dereference == DEREF_NEVER)) + && x->dereference == DEREF_NEVER) +#endif + ) { if (! create_hard_link (src_name, dst_name, false, false, dereference)) goto un_backup; @@ -2632,8 +2635,11 @@ copy_internal (char const *src_name, char const *dst_name, /* If we've just created a hard-link due to cp's --link option, we're done. */ if (x->hard_link && ! S_ISDIR (src_mode) +#if ! defined HAVE_LINKAT && !(LINK_FOLLOWS_SYMLINKS && S_ISLNK (src_mode) - && x->dereference == DEREF_NEVER)) + && x->dereference == DEREF_NEVER) +#endif + ) return delayed_ok; if (copied_as_regular) diff --git a/tests/cp/link-deref.sh b/tests/cp/link-deref.sh index e56d592..b249fce 100755 --- a/tests/cp/link-deref.sh +++ b/tests/cp/link-deref.sh @@ -19,8 +19,7 @@ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src print_ver_ cp -if grep '^#define HAVE_LINKAT 1' "$CONFIG_HEADER" > /dev/null \ - && grep '^#define LINK_FOLLOWS_SYMLINKS 0' "$CONFIG_HEADER" > /dev/null; then +if grep '^#define HAVE_LINKAT 1' "$CONFIG_HEADER" > /dev/null; then # With this config (which is the case on GNU/Linux) cp will attempt to # linkat() to hardlink a symlink. So now see if the current file system # supports this operation. -- 1.7.7.6
