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 For the above case we'll need to skip parts of the test I think, depending on the above 2 config vars. thanks, Pádraig
>From 3cc98a94d79c2f46f0c0bb70007987f377a65c83 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. --- src/copy.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/copy.c b/src/copy.c index 0f044d0..3f148f1 100644 --- a/src/copy.c +++ b/src/copy.c @@ -2481,8 +2481,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; @@ -2621,8 +2624,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) -- 1.7.7.6
