bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#6960: mv refuses to move a symlink over a hard link to the same file


From: Eric Blake
Subject: bug#6960: mv refuses to move a symlink over a hard link to the same file
Date: Tue, 31 Aug 2010 17:30:19 -0600
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8) Gecko/20100806 Fedora/3.1.2-1.fc13 Mnenhy/0.8.3 Thunderbird/3.1.2

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   address@hidden    +1-801-349-2682
Libvirt virtualization library http://libvirt.org





reply via email to

[Prev in Thread] Current Thread [Next in Thread]