bug-coreutils
[Top][All Lists]
Advanced

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

mv and hard links


From: Eric Blake
Subject: mv and hard links
Date: Thu, 10 Mar 2005 16:20:26 +0000

This may be worthy of raising an issue with the austin group, but I thought I'd 
ask here first.  A complaint was raised on the cygwin list that the following 
sequence had no interactive prompt:

$ uname
CYGWIN_NT-5.0
$ touch a
$ ln a b
$ mv -i a b
$ echo $?
0
$ mv --version | head -n 1
mv (GNU coreutils) 5.3.0

Further checking shows that other implementations have different behavior, and 
that the coreutils behavior is platform-independent:

$ uname -a
SunOS perth 5.8 Generic_108528-15 sun4u sparc SUNW,Sun-Blade-100 Solaris
$ touch a
$ ln a b
$ /usr/xpg4/bin/mv -i a b
mv: a and b are identical
$ echo $?
2
$ mv --version | head -n 1
mv (GNU coreutils) 5.3.0
$ mv -i a b
$ echo $?
0

By my reading of POSIX, 
http://www.opengroup.org/onlinepubs/009695399/utilities/mv.html, neither 
implementation is compliant.  Step 1 requires that since b exists, -f is not in 
force, and -i is in force, that a prompt be issued before anything further is 
attempted.  Neither Solaris nor coreutils did this, and I can't think of a 
reason to justify their non-compliance.

Then, in step 2 (whether -i is omitted or the (missing) prompt of step 1 was 
answered affirmitively), POSIX requires that mv defer to rename(), and that if 
rename() suceeds that no further steps are taken.  rename() requires that "If 
the old argument and the new argument resolve to the same existing file, 
rename() shall return successfully and perform no other action."  Therefore, 
the POSIX behavior is that `mv a b' leave both a and b intact, and exit with 
status 0.  The Solaris behavior of printing a diagnostic and exiting non-zero 
is justifiable because users do not expect for mv to leave the source intact 
when it was successful.  And the coreutils behavior seems reasonable, 
especially since coreutils/src/copy.c documents that "POSIX mistakenly requires 
that such a rename call do *nothing* and return successfully", because by using 
the workaround of calling unlink() on the source when the two files are the 
same, `mv a b' has the same net behavior whether a and b are hard links or not. 
 The trick now is deciding what wording should be used to permit the desired 
behaviors, or deciding that coreutils behavior needs to be changed to become 
compliant.

--
Eric Blake




reply via email to

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