Subject: Re: bug#10686: mv: moving hardlink of a softlink to the softlink does nothing

From: Eric Blake <[email-masked]>
Date: Wed, 01 Feb 2012 08:01:05 -0700

On 02/01/2012 05:47 AM, Jim Meyering wrote:
> Bernhard Voelker wrote:
>> Playing around with the latest mv checkin,
>> I noticed another corner case:
>>
>> Create a file 'f', a symlink 'l' to it, and
>> then a hardlink 's' to that symlink:
>>
>>   $ touch f && ln -s f l && ln l s && ls -ogi
>>   total 0
>>   6444 -rw-r--r-- 1 0 Feb  1 08:52 f
>>   6462 lrwxrwxrwx 2 1 Feb  1 08:52 l -> f
>>   6462 lrwxrwxrwx 2 1 Feb  1 08:52 s -> f
> 
> Hi Bernhard,
> Thanks for the report.
> 
> Here, you've already gotten into questionable territory, since the
> idea of a hard link to a symbolic link is not standardized.

Actually, POSIX 2008 _did_ standardize the notion of a hard link to a
symlink, thanks to linkat().

> For example, on FreeBSD 9.0, you cannot even create one:

That's a POSIX-compliance bug in FreeBSD.  In that case, the best we can
do is emulate it by creating a new symlink with identical contents and
owner and as much of the timestamp as lutimens will allow.

> 
> It's a standards and kernel issue.
> POSIX explicitly says (of rename)
> 
>     If the old argument and the new argument resolve to the same existing
>     file, rename( ) shall return successfully and perform no other action.
> 
> though that particular wording might be slated to change with POSIX 2008,
> to allow different (more desirable) behavior.  Search the austin-group
> archives if you need to be sure.

The wording for rename(2) did not change, but the wording for mv(1)
_did_ change to allow slightly more desirable behavior.  Here's the
latest wording, as modified by the latest bug report:

http://austingroupbugs.net/view.php?id=534

If the source_file operand and destination path resolve to either the
same existing directory entry or different directory entries for the
same existing file, then the destination path shall not be removed, and
one of the following shall occur:
 a. No change is made to source_file, no error occurs, and no diagnostic
is issued.
 b. No change is made to source_file, a diagnostic is issued to standard
error identifying the two names, and the exit status is affected.
 c. If the source_file operand and destination path name distinct
directory entries, then the source_file operand is removed, no error
occurs, and no diagnostic is issued.

The mv utility shall do nothing more with the current source_file, and
go on to any remaining source_files.

> Also, I don't know whether the above wording applies to this particular
> case of two hard links to the same symlink.  Again, I think we're in
> unspecified territory.

POSIX actually specifies this quite well - two hardlinks to the same
symlink qualify as an instance of two file names that resolve to the
same inode after path resolution as checked with lstat().

-- 
Eric Blake   [email-masked]    +1-919-301-3266
Libvirt virtualization library http://libvirt.org