>From 1893578fb0cdbb1875a42bc86cad452f6c62e5dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= 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