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

From: Pádraig Brady <[email-masked]>
Date: Sat, 02 Nov 2013 00:07:46 +0000

On 10/31/2013 09:28 PM, Gian Piero Carrubba wrote:
> * [Thu, Oct 31, 2013 at 02:54:59PM +0100] Gian Piero Carrubba:
>> Oh... I was tweaking a bit the last patch posted by Bernhard in order to let it be POSIX compliant (but now I have to add: "for my interpretation of POSIX"), but didn't had the time to complete before going to work.  Will probably finish it up anyway this evening or tomorrow, at this point at least for comparing how far we're currently are from "POSIX".
> 
> Here it is.
> First of all, sorry for having generated a lot of noise. I completely misunderstood the meaning of --no-preserve=links. Having get rid of that, the differences in the results of the tests are a lot less.
> 
> $ fgrep "DIFFERENCE in Test: " testit.log | sed 's/^.*: //'
> cp  -l   filelink ...
> cp  -l  --preserve=links filelink ...
> cp -L -l   filelink ...
> cp -L -l  --preserve=links filelink ...
> cp -L -l -R  filelink ...
> cp -L -l -R --preserve=links filelink ...
> cp -H -l   filelink ...
> cp -H -l  --preserve=links filelink ...
> cp -H -l -R  filelink ...
> cp -H -l -R --preserve=links filelink ...
> 
> I think they are all legit (full log and differences summary attached).
> 
> * Changes with regard to the last patch posted by Bernhard.
> 
> === Minor changes
> 
> - use 'dereference' instead of 'deref' in order to be consistent with   'x->dereference' and for passing the "grep test"[0]
> - use 'command_line_arg' instead of 'cli_arg' in order to be consistent   with an already used variable and for passing the "grep test"
> - move up the declaration of bool dereference in order to use it for   every invocation of create_hard_link()
> - clean up the initialization of 'flags' in create_hard_link()
> 
> [0] i.e.: http://jamie-wong.com/2013/07/12/grep-test/
> 
> === Major changes
> 
> - dereference by default (i.e.: unless --no-dereference is used) the   source files.
>   I promise that I will not insist anymore :), but I really think this   is important for consistency from a user point of view.
> 
> Ciao,
> Gian Piero.

So far we have Bernhard's slightly less invasive patch
which is an improvement, and behaves as per this table:

            Old  New BSD
          +-------------
  ln      | S    =   T
  ln -L   | T    =   T
  ln -P   | S    =   S
  cp -l   | S    S   -
  cp -lL  | S    T   -
  cp -lP  | NS   S   -
  cp -Rl  | NS   S   -
  cp -RlL | S    T   -
  cp -RlP | NS   S   -

  NS = New symlink
  S = hard link to symlink
  T = hard link to symlink target

Furthermore my previously noted POSIX interpretation,
and Gian's preference and patch, is to also
deref in the 'cp -l' case above (to turn it to a T).

There are valid arguments to doing that.
1. Follows naturally from standard cp which would create files in the dest
2. POSIX seems to imply we should operation on target without -P
3. A hardlink to a relative symlink may become invalid when in a different dir

Arguments against doing it would be:
1. It would be a little more invasive given the less specific cp command.
2. would be inconsistent with `ln`. Though not on BSD. Now we're free to
change ln to hardlink to targets rather than to symlinks by default,
and that may be more natural as per the 3 points above.
Though that would be more invasive again.

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,
Pádraig.