GNU bug report logs -
#6960
mv refuses to move a symlink over a hard link to the same file
Previous Next
Full log
Message #11 received at submit <at> debbugs.gnu.org (full text, mbox):
On 08/31/2010 04:48 PM, Davide Brini wrote:
> A simpler example is something like
>
> $ touch New_York
> $ ln -s New_York New_York.sym
> $ mv New_York.sym New_York
> mv: `New_York.sym' and `New_York' are the same file
>
> I think the reason is that when the source is a symbolic link, mv operates
> on the symlink itself, not the file it points to. So, it can't rename the
> symlink, because if successful that would imply having two entries named
> "New_York" in the same directory.
Not quite. POSIX specifies that:
http://www.opengroup.org/onlinepubs/9699919799/utilities/mv.html
If the source_file operand and destination path name the same existing
file, then the destination path shall not be removed, and one of the
following shall occur:
1. No change is made to source_file, no error occurs, and no
diagnostic is issued.
2. No change is made to source_file, a diagnostic is issued to
standard error identifying the two names, and the exit status is affected.
3. 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 question boils down to whether "New_York" and "New_York.sym" name
the same file (stat semantics), or whether, since mv generally operates
on symlinks rather than dereferencing them, they are distinct files
(lstat semantics).
Solaris /usr/xpg4/bin/mv (which is supposedly POSIX-compliant, although
we could debate that) goes ahead with the move:
$ touch a
$ ln -s a b
$ /usr/xpg4/bin/mv b a
$ echo $? ?
0 a
$ readlink a
a
Certainly, the underlying rename() call is allowed to replace a file
with a symlink, even if the symlink was to the file that it was
replacing (and thus will create an ELOOP situation on the symlink while
losing the contents that were pointed to). So, in that regards, you
could argue that Solaris' behavior is dangerous (it lost data) while
coreutils is playing it safe, when the destination has a link count of 1
in this simplified example. But when the destination has a link count
of 2, there is no data loss, so the original example seems like it is
pointing out a case where coreutils is over-strict.
And I would argue that the strict POSIX wording says that we should only
be refusing to move if the two files have the same inode; in both the
original and simplified examples, the symlink has a different inode than
the file it would be overwriting, so I think POSIX mandates that the
data destruction happen rather than the coreutils behavior.
Maybe this would argue for a POSIXLY_CORRECT behavior choice? :(
Maybe we need to raise this as a question to the Austin Group to argue
that coreutils behavior should be permitted?
> If this is really the reason for the
> error, the error message could probably be improved.
This part is true - the error message could definitely be more precise,
if we decide that POSIX even lets us issue an error in the first place.
--
Eric Blake eblake <at> redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
This bug report was last modified 13 years and 179 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.