Subject: bug#15173: [cp] --link overrides dereference settings

From: Pádraig Brady <[email-masked]>
Date: Mon, 04 Nov 2013 09:37:07 +0000

On 11/04/2013 12:48 AM, Bernhard Voelker wrote:
> On 11/02/2013 01:07 AM, Pádraig Brady wrote:
>> So I would be 60:40 for going with Gian's addition
>> of dereferencing with just `cp -l`, and I would be
>> 60:40 against changing the behavior of `ln` even though
>> it would now be inconsistent with `cp -l` (and still inconsistent with BSD).
> 
> Thanks for the summary.
> 
> After playing a bit more, I'd also tend to use Gian's solution:
> hard links to symbolic links are probably not that useful, because
> * they have the same owner/group as the original symbolic link which
>   could lead to problems with permissions during removal of the symlink
>   in a sticky dir like /tmp), and
> * the target cannot be changed without creating the symlink again
>   which is problematic to remember in both places.
> 
> BUT I'm not happy at all with the following case:
> 
>   $ : > file
>   $ ln -s file filelink
>   $ src/cp --link filelink dst--link
>   $ src/cp --link -R filelink dst--link-R
>   $ ls -ldogi file filelink dst--link dst--link-R
>   537364 -rw-r--r-- 2 0 Nov  4 01:30 dst--link
>   537365 lrwxrwxrwx 2 4 Nov  4 01:30 dst--link-R -> file
>   537364 -rw-r--r-- 2 0 Nov  4 01:30 file
>   537365 lrwxrwxrwx 2 4 Nov  4 01:30 filelink -> file
> 
> That's exactly what Gian was worried about in a different case
> of my solution: it *matters* whether the rather unrelated -R option
> is specified or not. ;-(
> 
> It got late again. I'll have a look tomorrow again - maybe there
> are no side effects with the following:
> 
> diff --git a/src/cp.c b/src/cp.c
> index 7bc8630..78c0a04 100644
> --- a/src/cp.c
> +++ b/src/cp.c
> @@ -1135,7 +1135,7 @@ main (int argc, char **argv)
> 
>    if (x.dereference == DEREF_UNDEFINED)
>      {
> -      if (x.recursive)
> +      if (x.recursive && ! x.hard_link)
>          /* This is compatible with FreeBSD.  */
>          x.dereference = DEREF_NEVER;
>        else

Yes I didn't consider -R in the table as I don't see any reason
for it to behave differently when -l is specified (and -l aplies
neither to POSIX or BSD (comment)).  So the above adjustment
looks correct to me.

thanks,
Pádraig.