[Top][All Lists]
[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
- mv and hard links,
Eric Blake <=