Fri Aug 23 20:29:12 CEST 2013 Gian Piero Carrubba * DRAFT diff -rN -u old-coreutils/src/copy.c new-coreutils/src/copy.c --- old-coreutils/src/copy.c 2013-08-23 22:16:15.938940800 +0200 +++ new-coreutils/src/copy.c 2013-08-23 22:16:15.942940823 +0200 @@ -1566,10 +1566,15 @@ be created as a symbolic link to SRC_NAME. */ static bool create_hard_link (char const *src_name, char const *dst_name, - bool replace, bool verbose) + bool replace, bool verbose, bool dereference) { - /* We want to guarantee that symlinks are not followed. */ - bool link_failed = (linkat (AT_FDCWD, src_name, AT_FDCWD, dst_name, 0) != 0); + int flags; + if (dereference) + flags = AT_SYMLINK_FOLLOW; + else + flags = 0; /* We want to guarantee that symlinks are not followed. */ + + bool link_failed = (linkat (AT_FDCWD, src_name, AT_FDCWD, dst_name, flags) != 0); /* If the link failed because of an existing destination, remove that file and then call link again. */ @@ -1582,7 +1587,7 @@ } if (verbose) printf (_("removed %s\n"), quote (dst_name)); - link_failed = (linkat (AT_FDCWD, src_name, AT_FDCWD, dst_name, 0) != 0); + link_failed = (linkat (AT_FDCWD, src_name, AT_FDCWD, dst_name, flags) != 0); } if (link_failed) @@ -1748,7 +1753,10 @@ /* Note we currently replace DST_NAME unconditionally, even if it was a newer separate file. */ if (! create_hard_link (earlier_file, dst_name, true, - x->verbose)) + x->verbose, + x->dereference == DEREF_ALWAYS + || (x->dereference == DEREF_COMMAND_LINE_ARGUMENTS + && command_line_arg))) { goto un_backup; } @@ -2078,7 +2086,10 @@ } else { - if (! create_hard_link (earlier_file, dst_name, true, x->verbose)) + if (! create_hard_link (earlier_file, dst_name, true, x->verbose, + x->dereference == DEREF_ALWAYS + || (x->dereference == DEREF_COMMAND_LINE_ARGUMENTS + && command_line_arg))) goto un_backup; return true; @@ -2389,7 +2400,10 @@ && !(LINK_FOLLOWS_SYMLINKS && S_ISLNK (src_mode) && x->dereference == DEREF_NEVER)) { - if (! create_hard_link (src_name, dst_name, false, false)) + if (! create_hard_link (src_name, dst_name, false, false, + x->dereference == DEREF_ALWAYS + || (x->dereference == DEREF_COMMAND_LINE_ARGUMENTS + && command_line_arg))) goto un_backup; } else if (S_ISREG (src_mode)